1296: [SCOI2009]粉刷匠

来源:互联网 发布:互联网运营书籍 知乎 编辑:程序博客网 时间:2024/04/28 21:50

题目链接

题目大意:给定n*m的木板,每个点需要刷成1和0两种颜色之一,每次只能刷一行中连续的一段,一个点只能刷一次,求T次刷子最多能刷对多少个点

题解:不错的dp
f[i][j]ijO(m3)k使k[k+1,r]0k<r便

f[m][i]0im1

O(nm3)

我的收获:独立性,dp+dp

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int M=55;int n,m,t,ans;int sum[M],f[M][M],dp[M][2505];char s[M];void init(){    cin>>n>>m>>t;    for(int i=1;i<=n;i++){        scanf("%s",s+1);        for(int j=1;j<=m;j++) sum[j]=sum[j-1]+s[j]-'0';        memset(f,0,sizeof(f));        for(int j=1;j<=m;j++)            for(int r=1;r<=m;r++)                for(int k=0;k<r;k++){                int tmp=sum[r]-sum[k];//[k,r]中1的个数                 f[r][j]=max(f[r][j],f[k][j-1]+max(tmp,r-k-tmp));//1和0取max             }        for(int j=1;j<=t;j++)            for(int k=0;k<=min(m,j);k++)                dp[i][j]=max(dp[i][j],dp[i-1][j-k]+f[m][k]);    }    for(int i=1;i<=t;i++) ans=max(ans,dp[n][i]);    printf("%d\n",ans);}int main(){    init();    return 0;}