【2017"百度之星"程序设计大赛 - 资格赛】 度度熊与邪恶大魔王
因为技能的效果和花费是不会变的;
所以,考虑预处理m个技能达成一定的伤害最少需要的魔法石数量;
可以把对这m个技能做一个类似的完全背包就可以了.
(对11种不同的防御值都做一遍)
最后对每个怪兽,O(1)输出;
(分类输出)
0
#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;
}