HDU-7110 (DP)

题目链接在这里:Problem - 7110 (hdu.edu.cn)

因为赛后是在洛谷上评测的,所以没有加多组数据

(赛后被告知这题洛谷上有原题的时候 内心一万匹草泥马奔过……)

我们需要考虑的只有两种情况,一种是打完k发子弹以后还剩了子弹,一种是打完k发子弹以后正好没子弹了。

这两种情况是有区别的,以同一列为例,如果当前k发子弹打完以后正好没了,那么后面如果跟着有Y砖头就不能再打了,如果还有子弹的话是还可以再打的。

状态转移方程的话也要分两种,一种是刚好打完,一种是打完以后还剩。

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 const int MAX=205;
 4 int n,m,k,cnt;
 5 int fa[MAX][MAX],fb[MAX][MAX],a[MAX][MAX],b[MAX][MAX],dd[MAX][MAX];// a无限 b刚好 
 6 bool c[MAX][MAX];
 7 char s[MAX][MAX];
 8 int main(){
 9     freopen ("k.in","r",stdin);
10     freopen ("k.out","w",stdout);
11     int i,j,zt,z;
12     scanf("%d%d%d",&n,&m,&k);
13     for (i=1;i<=n;i++)
14         for (j=1;j<=m;j++){
15             scanf("%d %c",&dd[i][j],&s[i][j]);
16             if (s[i][j]=='Y') c[i][j]=true;
17             else c[i][j]=false;
18         }
19 //    for (i=1;i<=n;i++) {for (j=1;j<=m;j++) cout<<dd[i][j]<<' ';cout<<endl;}
20 //    for (i=1;i<=n;i++) {for (j=1;j<=m;j++) cout<<c[i][j]<<' ';cout<<endl;}
21     for (i=1;i<=m;i++){
22         cnt=0;
23         for (j=n;j>=1;j--){
24             if (c[j][i])
25                 a[i][cnt]+=dd[j][i];
26             else{
27                 cnt++;
28                 a[i][cnt]=a[i][cnt-1]+dd[j][i];
29                 b[i][cnt]=a[i][cnt];
30             }
31         }
32     }
33     for (i=1;i<=m;i++)
34         for (j=0;j<=k;j++)
35             for (z=0;z<=min(j,n);z++){
36                 fa[i][j]=max(fa[i][j],fa[i-1][j-z]+a[i][z]);
37                 if (z!=0) fb[i][j]=max(fb[i][j],fa[i-1][j-z]+b[i][z]);
38                 if (j-z>0) fb[i][j]=max(fb[i][j],fb[i-1][j-z]+a[i][z]);
39             }
40     printf("%d",fb[m][k]);
41     return 0;
42 }
未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
原文地址:https://www.cnblogs.com/keximeiruguo/p/15201303.html