摘要:下面有别人的题解报告,并且不止这一个状态压缩题的哦····http://blog.csdn.net/accry/article/details/6607703下面是我的代码,代码很挫,绝对有很大的优化的空间···· 1 #include 2 #include 3 int dp[2][(1 2 #include 3 int dp[2][400]; 4 int st[400]; 5 //检查一行的奶牛放置情形是否合理 6 //即是否有相邻的两个1,没有返回true 7 bool checkHori(int state)
阅读全文
摘要:推荐网址,下面是别人的解题报告:http://www.cnblogs.com/chasetheexcellence/archive/2012/04/16/poj2441.html里面有状态压缩论文的链接,可以看看。该解题报告中用的是二维数组,但是很显然的是,递推式中的下一行只与上一行有关,类似于最长公共子序列,可以用滚动数组,在滚动数组后发现只用一个数组就可以了。至于是不是要和0-1背包一样得按从大到小的顺序,我没有,我的状态是从小到大的顺序,但是也AC了。如果不用滚动数组,会超内存。自己动手退一下,就能从滚动数组推到只用一个数组的情形。然后我就直接贴我的代码,注释就在代码中 1 #inclu
阅读全文
摘要:给一个字符串,求插入最少的字符使之成为回文,回文就是顺着读和逆着读是一样的。。。针对这个性质,把一个字符串化为两个,一个顺着,一个逆着,然后找一次最长公共子序列,插入的最少字符数即为字符串的长度-最长公共子序列的长度。另一种做法(我自己想太多),是从2序列比对中找的灵感,和最长公共子序列的做法差不多,但是效果不好,2序列比对可用来解再复杂一点点的问题会更好。。。2序列比对,中间有插入,删除,替换三种操作,给每种操作(比对)赋予代价值。。求两个序列的最优比对值照抄《算法设计与分析导论》中P140转移方程为见代码中的注释:贴代码:先贴LCS的代码:View Code 1 #include <
阅读全文
摘要:最长公共子序列,照抄《算法设计与分析导论》P138-140设输入的两个字符串分别为a1,a2,```,am(串a)b1,b2,````,bn(串b)设d(i,j)为字符串a1,a2,`````,ai和b1,b2,```,bj的最长公共子序列的长度如果a[i] == b[j],那么d(i,j) = d(i-1,j-1)+1;如果a[i] != b[j],那么 d(i,j) = max(d(i-1,j) , d(i,j-1))边界条件为d(0,0) = d(0,j) = d(i,0) = 0,1 <= i <= m,1 <= j <= n中间为节省空间,用到滚动数组,我为了
阅读全文
摘要:照抄刘汝佳的《算法竞赛入门经典》(较薄的那本)P159 数字三角形两种写法,一个是记忆化搜索,一个是DP,其实之所以要用DP是因为解这个题时出现了大量重叠的子问题用d(i,j)记录从第i 行,第j列出发(从上往下)能得到的最大和(包括自己)转移方程为d(i,j) = a(i,j) + max(d(i+1,j) , d(i+1,j+1));还有一个问题就是关于#define max(a,b) a<b?a:b的用法如果写这样的式子 t = a + max(c,d),怀疑会出错,因为下面的递推式我本来没有写max()函数而是用的这个宏定义,但是就错了,一直出不来正确的结果,还不符合"
阅读全文
摘要:2031 - Dance Dance RevolutionAsia - Shanghai - 2000/2001//https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=32看代码中的注释View Code 1 //怀特先生跳舞 2 #include <cstdio> 3 #define MAXN 100005 4 #define INF 100000000 5 int cur; 6 int a[MAXN];
阅读全文
摘要:先按做完题目的时间排序,在确定自己要做哪些题后,先做时间短的,这样能保证等的时间是最短的,在这里,能保证罚时会是最少的。然后0-1背包,0-1背包时先只管价值最大,在背包完后当价值一样时,再管题目做的多,题目数量一样时再管罚时少。贴代码,代码中有注释:View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define INF 0x7fffffff//int类型中最大的正整数 5 using namespace std; 6 struct node1 7 { 8
阅读全文
摘要:把方差公式先变形为σ2 = (1/n)∑xi2-xa2xa为平均值。由于要求标准差最小,只需方差最小,平均值都是一样的,n也是一样的,这样原问题就变为求这n快小棋盘总分的平方和最小考虑左上角为(x1,y1),右上角为(x2,y2)的棋盘,设该棋盘切割K次后得到的K+1块矩形的总分平方和最小值为d[k,x1,y1,x2,y2]。该棋盘的总分平方和为s[x1,y1,x2,y2].则它可以沿着横线切,也可以沿着竖线切,然后选一块继续切(这里可以用递归完成)状态转移方程为d[k,x1,y1,x2,y2] = min{min{ d[k-1,x1,y1,a,y2] + s[a+1,y1,x2,y2] ,
阅读全文
摘要:题意就是给一个字符串,字符串中只含(,),[,].加入这四种字符,要你插入一些字符,使得这段字符串是正确的,要求加入的字符数目最少。正确的定义就是一般意义上的正确。。。。比如([)就是错误的,([])就是正确的。题目要求的是输出加入最少数量的字符后,字符串正确了,输出该正确的字符串,感觉DP一般会让你输出最少加多少个字符啊,结果让我输正确的结果,蒙了,我不会,就抄了别人的,下面的代码是别人的,但是我忘了从哪里抄来的了,反正是百度的。。。。。希望原作者勿怪。。。贴代码:注意注释View Code 1 //如果原括号出现(S'),[S'],只需用最少的步数把S'化为正确的即
阅读全文
摘要:记录我做的第一个数位DP,听起来好高深,呵呵````http://122.207.68.93/OnlineJudge/problem.php?cid=2031&pid=7这个题就是给你a,b。输出[a,b]中间有多少个happy number.仔细考虑happy number的定义发现,一个18位的数,它的平方和最大会为每位都取9,即9*9*18=1458.如果我先计算出了1-1500之间的happy number.任给你一个数(大于1500),要判断出它是不是happy number,就把它每位数的平方和算出来,如果该数是个happy number,那么它的平方和值也会是个happy
阅读全文
摘要:思路是把物品看成是无限的,就像做完全背包一样从小到大更新,而事实上每种物品的数量却是有限的,所以还必须用count[j]记录当拼成j面值时用了多少个面值为ai的硬币,当在考虑面值k能否拼成时,如果count[k-ai]时已经用掉了re个ai面值的硬币了,如果re >= 该面值硬币的数量了,面值k就不能拼成,因为没这么多硬币了,如果小于该面值硬币的数量,面值 k能拼成,且count[k]为count[k-ai]+1.View Code 1 #include <cstdio> 2 #include <cstring> 3 bool v[100010]; 4 int c
阅读全文
摘要:就是每个组中只要选择一种,然后0-1背包一下。View Code 1 #include <cstdio> 2 #include <cstring> 3 int main() 4 { 5 int n,m; 6 while(~scanf("%d%d",&n,&m)) 7 { 8 int f[200],A[200][200]; 9 if(n == 0 && m == 0) break;10 for(int i=0; i<n; i++)11 for(int j=1; j<=m; j++)12 ...
阅读全文
摘要:像这种恰好装满的情况可以用bool数组,恰好装满为true,否则为false。还有就是逆向推倒,0-1背包,f[i][j]表示有i个人,组成了j的体重,这样的话在考虑某人的情形时,f[i][j]为真的前提就是f[i-1][j-wi]为真,其中wi为这个人的体重View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 bool f[110][2500]; 5 int main() 6 { 7 int n,w[110],sum = 0; 8 scanf("%d\n&q
阅读全文
摘要:这题WA了很多遍,要不就是测试数据 3 1 2 3 输出173,要不就是6 5 5 5 5 5 5 输出-1.甚至有时候把程序改的题目上的测试数据都过不了,各种悲摧,其实我喜欢边写程序边想,这是个很差的习惯,我一定要改!!!这题是看别人的提示写出来的,首先设bool型数组f,令 f[i][j]表示一边长为i,另一边长为j的边可以组合出来,然后在所有可以组合出来的情形中找能组合成三角形且面积最大的。f[i][j]能组合出来的条件是对于加入新边li来说是f[i-li][j] 或f[i][j-li]能组合出来,初始条件是f[0][0]能组合出来。因为题目中说了要用掉所有的栏杆,所以我只考虑两条边,剩
阅读全文
摘要:二进制压缩,看背包九讲啦,写的很详细了,不赘述````先贴不要求恰好装满的情形POJ 1276二进制压缩: 1 #include <cstdio> 2 #include <cstring> 3 int f[100005];//容量为i时最多能装多少 4 int p[12000];//物品拆分 5 int main() 6 { 7 int n,cash; 8 while(~scanf("%d%d",&cash,&n)) 9 {10 int vi,num;//物品价值,数量11 int cur = 0;12 memset(f,...
阅读全文
摘要:顺序求解是完全背包,逆序求解是0-1背包,自己想想View Code 1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 struct node 5 { 6 int cost,value; 7 } ; 8 node u[100005]; 9 int f[100005];10 int main()11 {12 int G,U;13 int T,cur;14 scanf("%d",&T);15 while(T--)16 {17 // freopen("in.
阅读全文
摘要:http://acm.zjut.edu.cn/不完全装满取值初始值都为0,恰好装满f[0]初始值为0,其他的为负无穷。得到的玩具的价格按从大到小排序,保证当玩具组合出的价格等于擎天柱价格时,玩具的数量会是最少的View Code 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 int f[10010]; 6 int c[10010]; 7 int main() 8 { 9 int n,m;10 int p[20];11 while
阅读全文
摘要:用f[i]记录当背包容量为i时,最大的重量。那么初始状态所有f[i]=0,一个物品一个物品考察,从容量大的背包开始到容量为1的背包结束,这时所有容量小的背包肯定都还没有放入该物品,这时原有的f[i]值如果小于f[i-pi]+pi,也就是未放这物品和放这物品后的容量值做比较,发现放这物品后总的容量值增大了,就放这物品。推荐看背包九讲,网上有下载,写得很好View Code 1 #include <cstdio> 2 int f[13000];//f[i]的值为背包容量为i时得到的最大价值 3 int w[3500]; 4 int d[3500]; 5 int main() 6 { 7
阅读全文