打砖块
題目鏈接:http://acm.ocrosoft.com/problem.php?cid=1629&pid=51
題目描述:
小紅很喜歡玩一個叫打磚塊的游戲,這個游戲的規(guī)則如下:
? ? ? ? 在剛開始的時候,有n行*m列的磚塊,小紅有k發(fā)子彈。小紅每次可以用一發(fā)子彈,打碎某一列當(dāng)前處于這一列最下面的那塊磚,并且得到相應(yīng)的得分。
? ? ? ? 如圖所示:
?
?某些磚塊在打碎以后,還可能將得到一發(fā)子彈的獎勵。最后當(dāng)所有的磚塊都打碎了,或者小紅沒有子彈了,游戲結(jié)束。
? ? ? ? 小紅在游戲開始之前,就已經(jīng)知道每一塊磚在打碎以后的得分,并且知道能不能得到一發(fā)獎勵的子彈。小紅想知道在這次游戲中她可能的最大得分,可是這個問題對于她來說太難了,你能幫幫她嗎?
輸入
第一行有3個正整數(shù),n,m,k。表示開始的時候,有n行*m列的磚塊,小紅有k發(fā)子彈。
? ? ? ? 接下來有n行,每行的格式如下:
? ? ? ? f1 c1 f2 c2 f3 c3 …… fm cm
? ? ? ? 其中fi為正整數(shù),表示這一行的第i列的磚,在打碎以后的得分。ci為一個字符,只有兩種可能,Y或者N。Y表示有一發(fā)獎勵的子彈,N表示沒有。
?
所有的數(shù)與字符之間用一個空格隔開,行末沒有多余的空格。
對于20%的數(shù)據(jù),滿足1<=n,m<=5,1<=k<=10,所有的字符c都為N
對于50%的數(shù)據(jù),滿足1<=n,m<=200,1<=k<=200,所有的字符c都為N
對于100%的數(shù)據(jù),滿足1<=n,m<=200,1<=k<=200,字符c可能為Y
對于100%的數(shù)據(jù),所有的f值滿足1<=f<=10000
?
輸出
僅一個正整數(shù),表示最大的得分。
樣例輸入
3 4 2 9 N 5 N 1 N 8 N 5 N 5 Y 5 N 5 N 6 N 2 N 4 N 3 N樣例輸出
13思路:先將輸入的數(shù)據(jù)預(yù)處理,先求出每一列用ans顆子彈來打j列所能得到的最打分?jǐn)?shù),最后再用三層循環(huán)得出m行k顆子彈所能得到的最大分?jǐn)?shù)。這里有一個坑點,碰到能加子彈的磚塊時,你不一定能直接不加子彈直接加磚塊的分?jǐn)?shù),如果你只有三顆子彈,加次數(shù)的磚塊在第四個時,你就不能直接加第四塊磚塊的分?jǐn)?shù),所以就需要在代碼中分兩種情況處理。
?
代碼:
#include<stdio.h> int max(int x,int y) {if(x>y)return x;elsereturn y; } int main() {int n,m,k;int score[205][205]={0};int bullet[205][205]={0};int dp[205][205]={0},dpy[205][205]={0};int f[205][205]={0},fy[205][205]={0};char t;//輸入scanf("%d %d %d",&n,&m,&k);for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){scanf("%d %c",&score[i][j],&t);if(t=='N')bullet[i][j]=0;elsebullet[i][j]=1;}}//預(yù)處理,將第j列用不同數(shù)量的子彈所能獲得分?jǐn)?shù)的情況列出來for(int j = 1; j <= m; j++){//所用的子彈數(shù)量,每一列都置0int ans = 0;for(int i = n; i>0; i--){//當(dāng)前磚塊打了能加子彈,相當(dāng)于不用子彈直接得分if(bullet[i][j])dp[j][ans]+=score[i][j];//不能加子彈,相當(dāng)于用了一顆子彈,所以ans++else{ans++;//在沒打子彈的基礎(chǔ)上加上這輪打掉的磚塊的分?jǐn)?shù)dp[j][ans] = dp[j][ans-1] + score[i][j];dpy[j][ans] = dp[j][ans-1] + score[i][j];}}}for(int i = 1; i <= m; i++){for(int j = 0; j <= k; j++){for(int gg = 0;gg <= j&& gg <= n; gg++){f[i][j]=max(f[i][j],f[i-1][j-gg]+dp[i][gg]);if(gg != 0)fy[i][j] = max(fy[i][j], f[i-1][j-gg] + dpy[i][gg]);// 后打當(dāng)前列if(j - gg > 0)fy[i][j] = max(fy[i][j], fy[i-1][j-gg] + dp[i][gg]);//先打當(dāng)前列}}}printf("%d\n",fy[m][k]);return 0; }?
總結(jié)
- 上一篇: python解析gff文件中的转录本
- 下一篇: win7c盘空间越来越小_教你两招电脑c