摘要: 一开始自己写了一个状态转移方程用res[i][j][k]表示前i个人已经完成A的j个部分B的k个部分所有过的最少时间。res[i][j][k]=min(res[i][j][k],max(res[i-1][j-s][k-t],s*A[i]+t*B[i]));很显然时间复杂度为O(n^5),显然是不可取的。看了大牛的思想后才知道可以用二分时间+DP来优化:令res[i][j]表示前i个人完成A的j个部分最多能完成B多少。res[i][j]=max(res[i][j],res[i-1][j-k]+(mid-k*A[i])/B[i]);当res[i][j]>=m 说明前i个人可以将任务完成,因此 阅读全文
posted @ 2012-04-04 16:40 书山有路,学海无涯 阅读(365) 评论(0) 推荐(0) 编辑
摘要: 状态压缩经典题目令res[i][j][k]表示第i行状态为第j个状态时,第i-1行的状态为第k个状态时最多能摆放的个数,令state[i][j]表示第i行的第j个状态,kk[i][j]表示第i行第j个状态所放的个数,len[i]表示第i行的可能的状态数。则:res[i][j][k]=max(res[i][j][k],res[i-1][k][l]+kk[i][j]);(0<=l<len[i-2])结果就是:在res[n][j][k]中找一个最大的。状态压缩经典题目令res[i][j][k]表示第i行状态为第j个状态时,第i-1行的状态为第k个状态时最多能摆放的个数,令state[i] 阅读全文
posted @ 2012-04-01 22:08 书山有路,学海无涯 阅读(271) 评论(0) 推荐(0) 编辑
摘要: 令res[i][j]表示从str[i]到str[j]需要添加字符的个数;如果str[k]与str[i]匹配, res[i][j]=min(res[i][j], res[i+1][k-1]+res[k+1][j]);如果str[k]与str[j]匹配, res[i][j]=min(res[i][j],res[i][k-1]+res[k+1][j-1] );如果str[k]与str[i]和str[j]都不匹配,res[i][j]=min(res[i][j],res[i][k-1]+res[k+1][j]+1 );#include<iostream>#include<cstdio& 阅读全文
posted @ 2012-04-01 11:46 书山有路,学海无涯 阅读(213) 评论(0) 推荐(0) 编辑
摘要: 令res[i][s1][k]表示第i行状态为s1,前i行摆放棋子的个数为k的方案个数;res[i][s1][k]=∑res[i-1][s2][k-inum]; inum表示第i行摆放的棋子个数,s1,s2表示第i行和第i-1行的状态,两种状态能够相容。#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define lld long long lld res[11][1025][101];int n,m;int init(int j,int state,int inu 阅读全文
posted @ 2012-04-01 11:43 书山有路,学海无涯 阅读(215) 评论(0) 推荐(0) 编辑
摘要: 经典的状态压缩和我的上一篇几乎一样,总的来说共有三种摆放方式:1、竖放 2、横放 3、不放代码如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define lld __int64 lld res[13][5000];int n,m;int dfs(int i,int j,int s1,int s2,int b1,int b2){ if(j>=m) { if(b1==0 && b2==0) res[i][s1]+=res[i-1][s2] 阅读全文
posted @ 2012-03-30 16:46 书山有路,学海无涯 阅读(188) 评论(0) 推荐(0) 编辑
摘要: 看了大牛的博客才知道这道题是周伟《状态压缩》中的原题,搜了一下该文档,并仔细看了一下,让我茅塞顿开,原来是这样的:令res[i][j]表示前i-1行全部铺满,第i行状态为j的方法总数(某位置有木板则为1,反之则为0);当我们确定了第i行的状态,才能够确定第i-1行的状态。所以我们枚举第i行的所有状态就ok了。总的来说一共有7放法:1、 长方形木板竖放2、 长方形木板横放3、 缺左上角的L形木板4、 缺右上角的L形木板5、 缺左下角的L形木板6、 缺右下角的L形木板7、 不放假如我们用dfs来遍历的话,我们可以用 i,j, s1,s2,b1, b2;分别表示当前第i行、当前第j列、i-1行状态为 阅读全文
posted @ 2012-03-30 16:21 书山有路,学海无涯 阅读(282) 评论(0) 推荐(0) 编辑
摘要: 令a[i]表示i不排在最后的总数,b[i]表示排在最后的总数,则递推公式如下:a[i]=a[i-1]+b[i-2];b[i]=b[i]+b[i-3];#include<iostream>#include<cstdio>#include<cstring>using namespace std;int a[56],b[56];int main(){ int i,n; a[1]=0; b[1]=1; a[2]=0; b[2]=1; a[3]=1; b[3]=1; for(i=4;i<=55;i++) { a[i]=a[i-1]+b[i-2]; ... 阅读全文
posted @ 2012-03-27 22:03 书山有路,学海无涯 阅读(169) 评论(0) 推荐(0) 编辑
摘要: 状态转移方程如下:res[i][j]=max{res[i-1][j-1]+f(str1[i],str2[j]),res[i-1][j]+f(str1[i],’-‘),res[i][j-1]+f(‘-‘,str2[j])};#include<iostream>#include<cstdio>#include<cstring>using namespace std;char str1[101],str2[101];int d[5][5]={ {5,-1,-2,-1,-3}, {-1,5,-3,-2,-4}, {-2,-3,5,-2,-2}, {-1,-2,-2, 阅读全文
posted @ 2012-03-26 09:14 书山有路,学海无涯 阅读(183) 评论(0) 推荐(0) 编辑
摘要: 虽然二分查找我已经写过很多遍了但是每次重新写的时候总是不那么顺畅,一些小错误不断出现,因此想写几个模板……..在不降序列中查找第一个大于goal的元素位置,若没有比goal大的返回最后一个,若都比goal大返回第一个:int find(int * res,int left,int right,int goal){ int mid; while(left < right) { mid = (left + right) >> 1; if(res[mid] > goal) right = mid; else ... 阅读全文
posted @ 2012-03-23 15:00 书山有路,学海无涯 阅读(732) 评论(2) 推荐(1) 编辑
摘要: Dilworth定理及其对偶定理的应用,定理的讲解请看如下博客http://blog.csdn.net/xiaohuan1991/article/details/6956629#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define MAX 123456789struct node{ int x,y;};node vert[20001];int res[20001];int cmp(node a,node b) 阅读全文
posted @ 2012-03-23 13:29 书山有路,学海无涯 阅读(245) 评论(0) 推荐(0) 编辑