[SCOI2009]画家[動的計画]

[BZOJ1296] [luoguP4158]

一見、私はそれがemmm表示されませんでした...

だから我々は唯一のボードはそれを行う方法があると思いしなければならないさ([I] [J fは\ ] \) 前を示す\(私は\)正方形ブラシ\(J \)右ブラシ正方形の数までの時間を

そして、正しいブラシグリッドの数をカウントする01バックパックまで行うことができる木材のN個の考えることは容易です

各グリッドのでそう列挙ブラッシュアップ\(J \)場合\(J \)与える少ない\を(私は\)

#include<bits/stdc++.h>
using namespace std;
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
const int N=50+5,M=2500+5,inf=0x3f3f3f3f,P=19650827;
int n,m,t,ans=0,sum[N],f[N][M],nw[N][N];
char S[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

int main(){
    freopen("in2.txt","r",stdin);
    //freopen("xor.out","w",stdout);
    rd(n),rd(m),rd(t);
    memset(f,0,sizeof(f));
    for(int x=1;x<=n;++x){
        scanf("%s",S+1);
        for(int i=1;i<=m;++i) sum[i]=sum[i-1]+(S[i]=='1');
        for(int i=1;i<=m;++i)//前i个格子 
        for(int j=1;j<=i;++j){//涂j次
            nw[i][j]=0;
            for(int k=0;k<i;++k)//由前k个格子转移过来 
                nw[i][j]=Max(nw[i][j],nw[k][j-1]+Max(sum[i]-sum[k],i-k-(sum[i]-sum[k])));
        }
        for(int i=1;i<=t;++i)
        for(int j=1;j<=Min(i,m);++j)
        f[x][i]=Max(f[x][i],f[x-1][i-j]+nw[m][j]);
    }
    for(int i=1;i<=t;++i) ans=Max(ans,f[n][i]);
    printf("%d",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/lxyyyy/p/11389356.html