2017百度之星資格賽 1003:度度熊與邪惡大魔王(DP)
阿新 • • 發佈:2017-08-06
solution nav normal ner 就會 預處理 display badge rate
度度熊與邪惡大魔王
Accepts: 3021 Submissions: 18787 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 度度熊為了拯救可愛的公主,於是與邪惡大魔王戰鬥起來。 邪惡大魔王的麾下有n個怪獸,每個怪獸有a[i]的生命值,以及b[i]的防禦力。 度度熊一共擁有m種攻擊方式,第i種攻擊方式,需要消耗k[i]的晶石,造成p[i]點傷害。 當然,如果度度熊使用第i個技能打在第j個怪獸上面的話,會使得第j個怪獸的生命值減少p[i]-b[j],當然如果傷害小於防禦,那麽攻擊就不會奏效。 如果怪獸的生命值降為0或以下,那麽怪獸就會被消滅。 當然每個技能都可以使用無限次。 請問度度熊最少攜帶多少晶石,就可以消滅所有的怪獸。 Input 本題包含若幹組測試數據。 第一行兩個整數n,m,表示有n個怪獸,m種技能。 接下來n行,每行兩個整數,a[i],b[i],分別表示怪獸的生命值和防禦力。 再接下來m行,每行兩個整數k[i]和p[i],分別表示技能的消耗晶石數目和技能的傷害值。 數據範圍: 1<=n<=100000 1<=m<=1000 1<=a[i]<=1000 0<=b[i]<=10 0<=k[i]<=100000 0<=p[i]<=1000 Output 對於每組測試數據,輸出最小的晶石消耗數量,如果不能擊敗所有的怪獸,輸出-1 Sample Input1 2 3 5 7 10 6 8 1 2 3 5 10 7 8 6Sample Output
6 18http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=774&pid=1003 就是一個完全背包,每個怪獸可以分開算,最後把答案加起來就是總的答案;由於怪獸的防禦值範圍很小,可以預處理出每一組技能下打死不同生命、不同防禦值的怪物消耗的最少晶石,對於每個怪物直接在其中取答案,比對於每個怪物求一次要快很多。 自己的代碼&講解:(太醜 了,什麽一直求到2*maxa也沒誰了。。)
1 /* 2 ans[i][j][b]表示防禦力為b的怪物 3 表示用前i種技能,造成恰好j的傷害消耗的最小晶石 4 ans[i][j][b]=min{ans[i-1][j-x*(p[i]-b)]+x*k[i]} 5 x表示第i種技能取x個(0<=x*(p[i]-b)<=j) 6 優化:http://blog.csdn.net/wumuzi520/article/details/7014830 7 ans[i][j][b]=min(ans[i-1][j][b],ans[i][j-(p[i]-b)][b]+k[i]【j>=p[i]-b】) 8 =>ans[j][b]=min(ans[j][b],ans[j-(p[i]-b)][b]+k[i] **i從小到大 9 */ 10 #include<cstdio> 11 #include<cstring> 12 #include<algorithm> 13 using namespace std; 14 typedef long long LL; 15 LL n,m; 16 LL maxb,maxp,bx,maxa; 17 LL a[100100],b[100100]; 18 LL ans[10001][11]; 19 LL k[1010],p[1010],ans1; 20 int main() 21 { 22 LL i,j,t,ze=(long long)0; 23 while(scanf("%lld%lld",&n,&m)==2) 24 { 25 maxb=0;maxp=0;maxa=0; 26 for(i=1;i<=n;i++) 27 { 28 scanf("%lld%lld",&a[i],&b[i]); 29 maxb=max(maxb,b[i]); 30 maxa=max(maxa,a[i]); 31 } 32 for(i=1;i<=m;i++) 33 { 34 scanf("%lld%lld",&k[i],&p[i]); 35 maxp=max(maxp,p[i]); 36 } 37 maxa=max(maxa,maxp); 38 /* 39 去掉以上這句,會讓類似 40 1 1 41 45 10 42 4164 327 43 的數據得出錯誤結果 44 */ 45 if(maxb>=maxp) 46 { 47 printf("-1\n"); 48 continue; 49 } 50 memset(ans,0x3f,sizeof(ans)); 51 memset(ans[0],0,sizeof(ans[0])); 52 for(bx=0;bx<=maxb;bx++) 53 { 54 for(i=1;i<=m;i++) 55 for(j=max(ze,p[i]-bx);j<=2*maxa;j++) 56 // { 57 //if(j>=p[i]-bx) 58 ans[j][bx]=min(ans[j][bx],ans[j-p[i]+bx][bx]+k[i]); 59 // } 60 t=0x3f3f3f3f; 61 for(j=2*maxa;j>=0;j--) 62 { 63 t=min(t,ans[j][bx]); 64 ans[j][bx]=min(ans[j][bx],t); 65 } 66 } 67 ans1=0; 68 for(i=1;i<=n;i++) 69 ans1+=ans[a[i]][b[i]]; 70 printf("%lld\n",ans1); 71 72 73 } 74 return 0; 75 }View Code
2017百度之星資格賽 1003:度度熊與邪惡大魔王(DP)
2017百度之星資格賽 1003:度度熊與邪惡大魔王(DP)