【BZOJ1296】粉刷匠(SCOI2009)-区间DP+资源分配型DP
2017-09-10 20:04
513 查看
测试地址:粉刷匠
做法:本题需要用到动态规划。
注意到,粉刷不能多于T次,就等同于将这些粉刷次数分配到每一条木板上,使得涂对的格子数最大,那么很容易写出状态转移方程:
f(i,j)表示前i条木板使用j次粉刷次数的情况下,能涂对的最大的格子数,g(i,j,k)表示第i条木板上用j次粉刷次数涂前k个格子,能涂对的最大的格子数,那么状态转移方程为:
f(i,j)=max{f(i−1,j−k)+g(i,k,m)|0≤k≤j}
那么g(i,k,m)要怎么求呢?因为每个格子最多被涂一次,所以可以看出,对于每条木板,可以做一个区间DP来求出g(i,j,k)的值,状态转移方程如下:
g(i,j,k)=max{g(i,j−1,l)+max([l,k]中的红色块数,[l,k]中的蓝色块数)|j−1≤l≤k−1}
如果暴力计算一个区间中某种颜色的块数,那么这个方程是O(nm4)的,未免太大。注意到颜色只有两种,所以我们只需用前缀和预处理出[1,k]内的红色块数,然后我们就可以随时O(1)得到一个区间内红色的块数和蓝色的块数,那么方程优化到O(nm3),再加上O(nmT)的求f,就可以通过此题了。最后的答案是max{f(n,i)}。
以下是本人代码:
做法:本题需要用到动态规划。
注意到,粉刷不能多于T次,就等同于将这些粉刷次数分配到每一条木板上,使得涂对的格子数最大,那么很容易写出状态转移方程:
f(i,j)表示前i条木板使用j次粉刷次数的情况下,能涂对的最大的格子数,g(i,j,k)表示第i条木板上用j次粉刷次数涂前k个格子,能涂对的最大的格子数,那么状态转移方程为:
f(i,j)=max{f(i−1,j−k)+g(i,k,m)|0≤k≤j}
那么g(i,k,m)要怎么求呢?因为每个格子最多被涂一次,所以可以看出,对于每条木板,可以做一个区间DP来求出g(i,j,k)的值,状态转移方程如下:
g(i,j,k)=max{g(i,j−1,l)+max([l,k]中的红色块数,[l,k]中的蓝色块数)|j−1≤l≤k−1}
如果暴力计算一个区间中某种颜色的块数,那么这个方程是O(nm4)的,未免太大。注意到颜色只有两种,所以我们只需用前缀和预处理出[1,k]内的红色块数,然后我们就可以随时O(1)得到一个区间内红色的块数和蓝色的块数,那么方程优化到O(nm3),再加上O(nmT)的求f,就可以通过此题了。最后的答案是max{f(n,i)}。
以下是本人代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; int n,m,t; int sum[55][55],f[55][2510]={0},g[55][2510][55]={0}; char s[110]; int main() { scanf("%d%d%d",&n,&m,&t); for(int i=1;i<=n;i++) { scanf("%s",s); sum[i][0]=0; for(int j=1;j<=m;j++) { if (s[j-1]=='1') sum[i][j]=sum[i][j-1]+1; else sum[i][j]=sum[i][j-1]; } } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int k=1;k<=m;k++) for(int l=j-1;l<k;l++) g[i][j][k]=max(g[i][j][k],g[i][j-1][l]+max(sum[i][k]-sum[i][l],k-l-sum[i][k]+sum[i][l])); for(int i=1;i<=n;i++) for(int j=1;j<=t;j++) for(int k=0;k<=min(j,m);k++) f[i][j]=max(f[i][j],f[i-1][j-k]+g[i][k][m]); int ans=0; for(int i=1;i<=t;i++) ans=max(ans,f [i]); printf("%d",ans); return 0; }
相关文章推荐
- bzoj1296 [SCOI2009]粉刷匠 区间dp+背包
- 【BZOJ1296】[SCOI2009]粉刷匠【区间DP】【背包DP】
- BZOJ_1296_[SCOI2009]粉刷匠_DP
- BZOJ1296 [SCOI2009]粉刷匠 【dp】
- BZOJ1296 [SCOI2009]粉刷匠 【dp】
- 【bzoj1296】【scoi2009】【粉刷匠】【dp】
- bzoj 1296 [SCOI2009]粉刷匠 (dp)
- bzoj 1296 [SCOI2009]粉刷匠 dp
- 【bzoj1296】【[SCOI2009]粉刷匠】多次背包dp及小小的优化
- BZOJ 1296: [SCOI2009]粉刷匠 dp
- bzoj1296 [SCOI2009]粉刷匠 ( 分组背包DP )
- bzoj 1296: [SCOI2009]粉刷匠 DP
- BZOJ 1296: [SCOI2009]粉刷匠( dp )
- BZOJ 1296 [SCOI2009]粉刷匠 - DP
- bzoj 1296: [SCOI2009]粉刷匠【dp+背包dp】
- [BZOJ1296][SCOI2009]粉刷匠(DP)
- bzoj 1296: [SCOI2009]粉刷匠(DP+DP)
- 【Dp】Bzoj1296 [SCOI2009] 粉刷匠
- bzoj-1296[SCOI2009]粉刷匠(dp)
- BZOJ 1296: [SCOI2009]粉刷匠 分组DP