【2017"百度之星"程序设计大赛

Link:

Description

Solution

因为技能的效果和花费是不会变的;
所以,考虑预处理m个技能达成一定的伤害最少需要的魔法石数量;
可以把对这m个技能做一个类似的完全背包就可以了.
(对11种不同的防御值都做一遍)
最后对每个怪兽,O(1)输出;
(分类输出)

NumberOf WA

0

Reviw


Code

#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define ri(x) scanf("%d",&x)
#define rl(x) scanf("%lld",&x)
#define rs(x) scanf("%s",x+1)
#define oi(x) printf("%d",x)
#define ol(x) printf("%lld",x)
#define oc putchar(' ')
#define os(x) printf(x)
#define all(x) x.begin(),x.end()
#define Open() freopen("F:\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 10;
const int M = 1000;
const int INF = 0x3f3f3f3f;

int n,m,cost[M+100];
LL f[N+10][M+100];
vector <int> v[N+10];

int main(){
    //Open();
    //Close();
    while(~ri(n)){
        ri(m);
        rep1(i,0,N) v[i].clear();
        rep1(i,1,n){
            int x,y;
            ri(x),ri(y);
            v[y].pb(x);
        }

        ms(cost,255);
        rep1(i,1,m){
            int x,y;
            ri(x),ri(y);
            if (cost[y]==-1)
                cost[y] = x;
            else
                cost[y] = min(cost[y],x);
        }

        bool solved = true;
        LL ans = 0;
        rep1(b,0,10){
            ms(f[b],INF);
            f[b][0] = 0;
            rep1(i,b+1,1000)
                if (cost[i]!=-1){
                    // c = cost[i] w = i - b;
                    rep1(j,0,1000)
                        if (f[b][j]<INF){
                            int nextj = j + i - b;
                            if (nextj > 1001) nextj = 1001;
                            f[b][nextj] = min(f[b][nextj],f[b][j] + cost[i]);
                        }
                }
            rep2(i,1000,1)
                f[b][i] = min(f[b][i],f[b][i+1]);

            int len = v[b].size();
            rep1(i,0,len-1){
                int x = v[b][i];
                if (f[b][x] >= INF){
                    solved = false;
                    break;
                }
                ans += f[b][x];
            }
        }
        if (solved){
            ol(ans);puts("");
        }
        else
            puts("-1");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626134.html