BZOJ 1296 粉刷匠(分组背包套DP)

摘要:
我刚开始思考网络流动的方向。每条线都是独立的。对于每一行,因为晶格只能染色一次,可以发现这是一个多阶段的决策问题。决定当前晶格是染色0还是染色1。让dp[i][j][k]表示当前行的第i个晶格已染色j次,而这种染色是k种颜色中最有效的晶格。明显的背包。每组最多选择一个。然后使用O计算团队背包。

刚开始往网络流的方向想。建不出图。。。

因为每次只能对一行进行染色。每一行都是独立的。

对于每一行,因为格子只能染一次,所以可以发现这是一个多阶段决策问题,这个决策就是当前格子染0还是染1.

令dp[i][j][k](k==0||k==1)表示当前行第i个格子用了j次染色,且这次染色染为k色 的最多有效格子。

这样我们用了O(n*m*m)得出了每一行用了v次染色获得的最多有效格子val。

显然的分组背包。每一个组最多选一种。再用O(V*n*m)求一遍分组背包即可。

总复杂度O((V+m)*m*n).

BZOJ 1296 粉刷匠(分组背包套DP)第1张BZOJ 1296 粉刷匠(分组背包套DP)第2张
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <iostream>
# include <vector>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <cmath>
# include <algorithm>
using namespace std;
# define lowbit(x) ((x)&(-x))
# define pi 3.1415926535
# define eps 1e-9
# define MOD 100000007
# define INF 1000000000
# define mem(a,b) memset(a,b,sizeof(a))
# define FOR(i,a,n) for(int i=a; i<=n; ++i)
# define FO(i,a,n) for(int i=a; i<n; ++i)
# define bug puts("H");
# define lch p<<1,l,mid
# define rch p<<1|1,mid+1,r
# define mp make_pair
# define pb push_back
typedef pair<int,int> PII;
typedef vector<int> VI;
# pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
int Scan() {
    int res=0, flag=0;
    char ch;
    if((ch=getchar())=='-') flag=1;
    else if(ch>='0'&&ch<='9') res=ch-'0';
    while((ch=getchar())>='0'&&ch<='9')  res=res*10+(ch-'0');
    return flag?-res:res;
}
void Out(int a) {
    if(a<0) {putchar('-'); a=-a;}
    if(a>=10) Out(a/10);
    putchar(a%10+'0');
}
const int N=2505;
//Code begin...

int val[55][55], dp[55][55][2], ans[2505];
char s[55][55];

int main ()
{
    int n, m, T;
    scanf("%d%d%d",&n,&m,&T);
    FOR(i,1,n) scanf("%s",s[i]+1);
    FOR(i,1,n) {
        mem(dp,0);
        FOR(j,1,m) FOR(k,1,j) {
            dp[j][k][0]=max(dp[j-1][k][0],max(dp[j-1][k-1][0],dp[j-1][k-1][1]))+(s[i][j]=='0');
            dp[j][k][1]=max(dp[j-1][k][1],max(dp[j-1][k-1][0],dp[j-1][k-1][1]))+(s[i][j]=='1');
        }
        FOR(j,1,m) val[i][j]=max(dp[m][j][0],dp[m][j][1]);
    }
    FOR(i,1,n) for (int j=T; j>=0; --j) for (int k=min(j,m); k>=1; --k)
        ans[j]=max(ans[j],ans[j-k]+val[i][k]);
    printf("%d
",ans[T]);
    return 0;
}
View Code

免责声明:文章转载自《BZOJ 1296 粉刷匠(分组背包套DP)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇pytcharm 断点调试Flasklayui select下拉菜单联动下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何用c语言调用c++做成的动态链接库

今天在做东西的时候遇到一个问题,就是如何在C语言中调用C++做的动态链接库so文件如果你有一个c++做的动态链接库.so文件,而你只有一些相关类的声明, 那么你如何用c调用呢,别着急,本文通过一个小小的例子,让你能够很爽的搞定.   链接库头文件:head.h class A { public: A();...

opencv配置过程 (cmake,vs2013,qt 5.4)

平台及软件: Windows 7 X86 Visual Studio 2013 OpenCV3.0.0 Cmake3.3 1、下载Windows下的安装文件OpenCV-3.0.0.exe,解压,选择需要的安装目录即可。(本文为F:\opencv) 注意相应的目录不能包含中文。 2、Cmake编译 执行CMake,用于把OpenCV的源码生成对应的VS工程...

c++中的.hpp文件

http://blog.chinaunix.net/uid-24118190-id-75239.html hpp,其实质就是将.cpp的实现代码混入.h头文件当中,定义与实现都包含在同一文件,则该类的调用者只需要include该hpp文件即可,无需再将cpp加入到project中进行编译。 而实现代码将直接编译到调用者的obj文件中,不再生成单独的obj,...

Qt之读取配置文件

一、读取配置文件增删功能与修改参数数据 1 #ifndef CONFIG_H 2 #define CONFIG_H 3 4 #define QS_FILEPATH "E:\woo\Code\Qt\APP_002_READCONF\config.ini" 5 6 #endif //CONFIG_H View Code 1 #ifndef MAINW...

《Linux内核Makefile分析》之 auto.conf, auto.conf.cmd, autoconf.h【转】

转自:http://blog.sina.com.cn/s/blog_87c063060101l25y.html 转载:http://blog.csdn.net/lcw_202/article/details/6661364 在编译构建性目标时(如 make vmlinux),顶层 Makefile 的 $(dot-config) 变量值为 1 。 在顶层...

uboot学习之三-----uboot启动第一阶段--start.S之一

uboot分为两个阶段:start.S是uboot的第一阶段。   一:引入start.S     u-boot.s找到start.S的入口       ①首先在C语言中整个项目的入口就是main函数(这是C语言规定的),所以如果要去了解C语言的项目,从main函数开始,这样才能分析,如果随便拿一个文件就开始看,最后看得一头雾水,对自己没有信心。怎么来找呢...