[bzoj1296][SCOI2009]粉刷匠

本文详细介绍了如何通过动态规划解决BZOJ 1296题目中的木板粉刷问题。文章提出了四种状态转移矩阵h、g、e、f,用于记录不同条件下的最优粉刷方案,并给出了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

n,m<=50  T<=2500

题解:dp大合集!!!!

h[k][i][j]表示第k个木板刷i到j最多能刷对几个,这个很好处理。

g[k][i][j]表示第k个木板前i个刷j次最多刷对几个 g[k][i][j]=max(g[j][l][j-1]+h[l+1][i]) 这个也很好处理

e[k][i]表示第k个木板刷i次最多能刷对几个,这个就从g里取一个最值就好啦。

f[i][j]表示前i个木板刷j次最多能刷对几个 f[i][j]=max(f[i-1][j-k]+e[i][k]) 这个也很好处理

总复杂度 n^3 + n^4 +n^2T

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1000000
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

int h[55][55];
int g[55][55];
int e[55][55]; 
int f[55][2505];
int n,m,T,num1,num2;
char st[55]; 

int main()
{
    n=read();m=read();T=read();
    for(int num=1;num<=n;num++)
    {
        scanf("%s",st+1);
        memset(h,0,sizeof(h));
        memset(g,0,sizeof(g));
        for(int i=1;i<=m;i++)
        {
            num1=num2=0;
            for(int j=i;j<=m;j++)    
            {
                if(st[j]=='0')num1++;
                else num2++;
                h[i][j]=max(num1,num2);
            }
        }    
        for(int k=1;k<=m;k++)
            for(int i=1;i<=m;i++)
                for(int j=0;j<i;j++)
                    g[i][k]=max(g[i][k],g[j][k-1]+h[j+1][i]);
        for(int k=1;k<=m;k++)
            for(int i=k;i<=m;i++)
                e[num][k]=max(e[num][k],g[i][k]);
    }    
    for(int j=1;j<=T;j++)
        for(int i=1;i<=n;i++)
            for(int k=1;k<=min(m,j);k++)
                f[i][j]=max(f[i][j],f[i-1][j-k]+e[i][k]);
    printf("%d",f[n][T]);
    return 0;
}

 

转载于:https://www.cnblogs.com/FallDream/p/bzoj1296.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值