BZOJ 1296 [SCOI2009]粉刷匠
来源:互联网 发布:c语言不等于号怎么打 编辑:程序博客网 时间:2024/05/17 05:59
一开始看错数据范围,搞了一个
这种做法的思路是,枚举当前状态,可以继续涂此层剩余,也可以涂他层,一分类讨论即可。
后来发现这种做法肯定有大量重复,而且每行之间独立,不必将每行的状态混在一起,于是每行dp搞用cost最多的得分,然后行与行之间分组dp就好了。
TLE:
#include<iostream>#include<cstdlib>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=55;const int maxt=2505;int n,m,t;char s[maxn][maxn];int sum[maxn][maxn];int dp[maxt][maxn][maxn];inline int getans(int x,int l,int r){ return max(sum[x][r]-sum[x][l-1],r-l+1-(sum[x][r]-sum[x][l-1]));}int main(){ scanf("%d%d%d",&n,&m,&t); for(int i=1;i<=n;i++) scanf("%s",s[i]+1);//初始化 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) sum[i][j]=sum[i][j-1]+(s[i][j]=='0'); for(int i=1;i<=n;i++) for(int k=1;k<=m;k++)dp[1][i][k]=getans(i,1,k); for(int i=2;i<=t;i++) { for(int j=1;j<=n;j++)//层数 { for(int k=1;k<=m;k++)//个数 { //本层状态 for(int l=k+1;l<=m;l++) dp[i][j][l]=max(dp[i][j][l],dp[i-1][j][k]+getans(j,k+1,l)); //别层状态 for(int l=j+1;l<=n;l++) for(int p=1;p<=m;p++) dp[i][l][p]=max(dp[i][l][p],dp[i-1][j][k]+getans(l,1,p)); } } } int ans=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) ans=max(ans,dp[t][i][j]); printf("%d",ans);}
AC:
#include<iostream>#include<cstring>#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;const int maxn=105;const int maxt=2505;int n,m,t;char s[maxn][maxn];int sum[maxn][maxn];int dp[maxn][maxt],f[maxn][maxn][maxn];inline int getans(int x,int l,int r){ return max(sum[x][r]-sum[x][l-1],r-l+1-(sum[x][r]-sum[x][l-1]));}int main(){ scanf("%d%d%d",&n,&m,&t); for(int i=1;i<=n;i++) scanf("%s",s[i]+1);//初始化 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) sum[i][j]=sum[i][j-1]+(s[i][j]=='0');//每层独立dp for(int i=1;i<=n;i++)//层数 { for(int l=1;l<=m;l++) f[i][1][l]=getans(i,1,l); for(int j=2;j<=m;j++)//次数 for(int k=j-1;k<=m;k++)//上次结尾 for(int l=k+1;l<=m;l++)//本次结尾 f[i][j][l]=max(f[i][j][l],f[i][j-1][k]+getans(i,k+1,l)); } /*for(int i=1;i<=m;i++) for(int j=i;j<=m;j++) printf("%d%c",f[1][i][j],j==m?'\n':' '); *///分组背包dp for(int i=1;i<=n;i++)//层数 for(int j=0;j<=t;j++)//上次剩余 for(int k=0;k<=min(m,j);k++)//本次使用 dp[i][j-k]=max(dp[i][j-k],dp[i-1][j]+f[i][k][m]); printf("%d",dp[n][0]); return 0;}
阅读全文
0 0
- [BZOJ 1296][SCOI2009]粉刷匠
- bzoj 1296: [SCOI2009]粉刷匠
- bzoj 1296 [SCOI2009]粉刷匠
- BZOJ 1296: [SCOI2009]粉刷匠
- BZOJ 1296: [SCOI2009]粉刷匠
- BZOJ 1296 [SCOI2009]粉刷匠
- BZOJ 1296 SCOI2009 粉刷匠 动态规划
- bzoj 1296: [SCOI2009]粉刷匠 DP
- BZOJ系列1296《[SCOI2009]粉刷匠》题解
- bzoj 1296 [SCOI2009]粉刷匠 dp
- BZOJ 1296: [SCOI2009]粉刷匠 动态规划
- BZOJ 1296: [SCOI2009]粉刷匠 背包
- bzoj 1296: [SCOI2009]粉刷匠 动态规划
- BZOJ 1296: [SCOI2009]粉刷匠 dp
- bzoj 1296 [SCOI2009]粉刷匠 (dp)
- 1296: [SCOI2009]粉刷匠
- 1296: [SCOI2009]粉刷匠
- bzoj 1296: [SCOI2009]粉刷匠(DP+DP)
- 04Python中的控制流语句
- luogu P1341 无序字母对
- 10.23(周一)
- Android 6.0动态申请权限
- JDBC纯驱动连接MySQL
- BZOJ 1296 [SCOI2009]粉刷匠
- 初识java多线程
- C#+AE加载shape图层
- JDK7中Executors源码概述
- 点菜系统e-r图
- STL学习之string类
- 05Python中的number数据类型
- cvCloneImage()内存泄漏解决方法, cvCloneImage()和cvCopy()的区别
- Jzoj4747 被粉碎的线段树