bzoj1296 [SCOI2009]粉刷匠 區間dp+揹包
阿新 • • 發佈:2019-01-28
每一條都是獨立的,所以可以分開處理
對於一條,粉刷一定是粉刷完完整的一條是最優的(不會有比它優的),所以列舉次數起點轉移
不同條之間就是分組揹包的關係了。。
碼:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int ff[5555],fff[5555],g[5555],tu[55][55],qsum1[55],qsum0[55],f[55][55],n,m,t,i,j,k,l; int main() { scanf("%d%d%d",&n,&m,&t); for(i=1;i<=t;i++)ff[i]=-999999999; for(i=1;i<=n;i++) { for(j=1;j<=m;j++){scanf("%c",&tu[i][j]);while(tu[i][j]!='0'&&tu[i][j]!='1')scanf("%c",&tu[i][j]); } } for(i=1;i<=n;i++) { for(j=1;j<=m;j++) fff[j]=-999999999; memset(qsum1,0,sizeof(qsum1)); memset(qsum0,0,sizeof(qsum0)); memset(g,0,sizeof(g)); memset(f,0,sizeof(f)); for(j=1;j<=m;j++) { qsum1[j]=qsum1[j-1]+ (tu[i][j]=='0'?0:1); qsum0[j]=qsum0[j-1]+ (tu[i][j]=='1'?0:1); } for(j=1;j<=m;j++) for(k=0;k<j;k++) for(l=1;l<=m;l++) { f[j][l]=max(f[k][l-1]+max(qsum1[j]-qsum1[k],qsum0[j]-qsum0[k]),f[j][l]); } for(j=1;j<=m;j++) { for(k=1;k<=m;k++) { g[j]=max(g[j],f[k][j]); } } for(j=1;j<=t;j++) { for(k=1;k<=m;k++) { if(j-k>=0)fff[j]=max(ff[j-k]+g[k],fff[j]); } } for(j=1;j<=t;j++)ff[j]=max(ff[j],fff[j]); } printf("%d",ff[t]); }