[SCOI2009]粉刷匠题解

[SCOI2009]粉刷匠

https://ac.nowcoder.com/acm/problem/20273

这道题你猛的一看呢没什么头绪,但你仔细一看呢,就会发现还不如猛的一看,嘿嘿,蒟蒻自己的理解如下;
看题的范围我们可以想到DP,很合适,50502500,然后就是我们dp定义的状态,看了很多大佬的 四维是真的想不到,理解的很难啊,还是太菜,蒟蒻定义一个三维一个二维,二维的很容易理解就是一个分组背包,那么关键是三维,如何把三维处理出来变成分组背包是一个技术活,首先我们定义dp[i][j][k],是什么意思呢,意思是i组涂j次k个长度的木板然后正确的个数, dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][l]+max(k-l里面最多的木板)之后处理出来就是直接分组背包搞

#include <bits/stdc++.h>
#define fio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define debug(x) cout << #x << ": " << x << endl;
#define debug1(x) cout<<"xxx"<<endl;
#define ll long long
#define ull unsigned long long
#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#define mse(a,b) memset(a,b,sizeof a);
using namespace std;
inline int read()
{
    int s = 0, w = 1;
    char ch = getchar();
    while (ch < 48 || ch > 57)
    {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
const int maxx=1e6+7;
const int mod=1e9+7;
int dp[55][55][3000];
char ans[55];
int pre[55];
int f[maxx];
int main()
{
    int n,m,t;
    cin>>n>>m>>t;
    for(int i=1; i<=n; i++)
    {
        scanf("%s",ans+1);
        for(int j=1; j<=m; j++)
        {
            pre[j]=pre[j-1]+(ans[j]=='1');
        }
        for(int j=1; j<=m; j++)
            for(int k=1; k<=m; k++)
                for(int l=0; l<k; l++)
                {
                    int tep=pre[k]-pre[l];
                    dp[i][j][k]=max(dp[i][j][k],dp[i][j-1][l]+max(tep,k-l-tep));
                }
    }
    for(int i = 1; i <= n; i++)
        for(int k = t; k > 0; k--)
            for(int j = 1; j <= min(k, m); j++)
            {
                f[k] = max(f[k], f[k - j] + dp[i][j][m]);

            }
            cout<<f[t]<<endl;
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务