bzoj1296: [SCOI2009]粉刷匠(DP)
1296: [SCOI2009]粉刷匠
题目:传送门
题解:
DP新姿势:dp套dp
我们先单独处理每个串,然后再放到全局更新:
f[i][k]表示当前串枚举到第i个位置,用了k次机会
F[i][j]则表示总答案
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cmath> 5 #include<algorithm> 6 using namespace std; 7 int n,m,t; 8 int f[55][55]; 9 int F[55][3100]; 10 char st[55];int a[55]; 11 int main() 12 { 13 scanf("%d%d%d",&n,&m,&t);getchar(); 14 memset(F,0,sizeof(F)); 15 for(int i=1;i<=n;i++) 16 { 17 scanf("%s",st+1); 18 a[0]=0;for(int j=1;j<=m;j++)a[j]=a[j-1]+st[j]-'0'; 19 memset(f,0,sizeof(f)); 20 for(int j=1;j<=m;j++) 21 for(int k=1;k<=min(j,t);k++) 22 for(int l=1;l<=j;l++) 23 { 24 int s=a[j]-a[l-1]; 25 f[j][k]=max(f[j][k],f[l-1][k-1]+max(s,(j-l+1)-s)); 26 } 27 for(int j=1;j<=t;j++) 28 for(int k=1;k<=min(m,j);k++) 29 F[i][j]=max(F[i][j],F[i-1][j-k]+f[m][k]); 30 } 31 int ans=1e-7; 32 for(int i=1;i<=t;i++)ans=max(ans,F[n][i]); 33 printf("%d\n",ans); 34 return 0; 35 }