07 2012 档案

摘要:这是一道可以用多重背包来写的题,但是这种方法速度很慢,2829MS。思路很简单,将多重背包转化为01背包,dp所对应的下标为钱数,如果能刚好凑到下标所对应的钱数,就赋为1。最后输出被赋为1的个数就是可能性。#include<stdio.h>#include<string.h>#define MAX_PRICE 1000000#define MAX_COIN 110void mk_list(int,int,int);int top=1,stk[MAX_PRICE];int main(){ int n,m; while(scanf("%d%d",& 阅读全文
posted @ 2012-07-30 23:50 等待电子的砹 阅读(239) 评论(0) 推荐(0) 编辑
摘要:这是一道二维的01背包,开始没有思路,是看了别人的解题报告才有了大方向,再自己写的。但是自己在细节上还是出了许多问题。 dp[][]的两个下表分别表示两条边,如果篱笆的长度刚好等于下标,说明有办法建出这么长的篱笆(比如给了1,3,4可以建成长度为5的篱笆,不能建成长度为6的篱笆),如果能,就将dp赋为1。由于这里是选择单个篱笆的过程,在这个过程中还不能加入判断是否能构成三角形,比如,再选取最后一块篱笆就构成了三角形,但如果在这里就加入判断,会导致选最后一块篱笆之前,不能构成三角形,这时的dp值为0,dp为0应该表示不能建成这么长的篱笆,而不能同时表示能否建成篱笆和能否构成三角形。判断能否... 阅读全文
posted @ 2012-07-30 20:57 等待电子的砹 阅读(602) 评论(0) 推荐(0) 编辑
摘要:这是一道多重背包,加了一点限制条件,要求不能让每一类型的砖头超过该类型的最大高度,这只需要加一个if语句就行了 if(j<=a[i]) dp[j]=max(dp[j],dp[j-hight[i]]+hight[i]) 值得注意的是,应该将每种类型的砖头根据限制高度进行排序,也就是说要先从最大高度小的开始选,比如这种数据:5 10 1;1 1 1;最大高度应该是6,如果不先从小的开始选,那么就会首先取符合要求的5 10 1,但是第二块砖头的限制高度是1,取了第一块砖头之后高度已经是5了,就不能再取1 1 1了。所以要先从最大高度小的开始取。 做这道题的时候,最开始没有想到上面的那... 阅读全文
posted @ 2012-07-30 12:17 等待电子的砹 阅读(152) 评论(0) 推荐(0) 编辑
摘要:这是一道01背包的问题,但是有一个地方我没有想到,所以花了很多时间。 题目给了每个银行的钱和被抓的概率,由于要抢尽量多的钱,所以要保证尽量不被抓,而抢多个银行之后不被抓的概率是抢每一个银行不被抓的概率之积,我竟然把这一点给忘了!导致我走了许多弯路,思路不能太死啊!dp[]表示抢到下标所对应的钱时,此时不被抓的概率,题目给出了最终不能高于被抓概率P,不被抓的概率就不能低于(1-P),所以最后只需要逆序遍历dp,找到第一个大于等于1-P的dp[i],就能够保证i最大,即抢到的钱最多。#include<stdio.h>#include<string.h>#define MAX 阅读全文
posted @ 2012-07-28 20:29 等待电子的砹 阅读(1185) 评论(0) 推荐(1) 编辑
摘要:这是一道01背包的变体。题目加了限制条件,当卡上金额大于等于5元时才能购买成功,我们不妨将这里的5元视为“0“,因为在DP过程中金额不能低于5,所以最后要用到的结果应该是dp[m-5]。既然我们保证了余额一直是大于等于5的,那么最后还能购买一次,所以,我们将最贵的一样菜留在最后,在DP的过程结束之后再购买,这样就能保证最后的余额最少。 开始,我在写这道题的时候由于觉得要剩5元,于是将循环改为了 for i 1 to n for j m+5 to 5 这样也是可以的,只是要注意最后结果应该使用dp[m],而不是dp[m+5]... 阅读全文
posted @ 2012-07-28 11:35 等待电子的砹 阅读(778) 评论(0) 推荐(1) 编辑
摘要:这是一道综合性的背包问题。题目给出了多组工作,每组工作的选择规则不同,有些组至少要选一项,有些组最多选一项,有些组任意选。 这道题花了很长时间,需要深入理解状态转移才能够明白。数组dp[i][j],表示第i组,时间剩余为j时的快乐值。每得到一组工作就进行一次DP,所以dp[i]为第i组的结果。下面对三种情况进行讨论。 第一类,至少选一项,即必须要选,那么在开始时,对于这一组的dp的初值,应该全部赋为负无穷,这样才能保证不会出现都不选的情况。状态转移方程为dp[i][k]=max{ dp[i][k],dp[i-1][k-cost[j]]+val[k],dp[i][k-cost[j]]+v... 阅读全文
posted @ 2012-07-26 23:25 等待电子的砹 阅读(1620) 评论(0) 推荐(1) 编辑
摘要:这是一道简单的分组背包,因为每种课可以有多种选择:花几天时间在该课上。一旦作出选择,就不能再选该课,就相当于有多组物品,每组内的物品互相冲突,最多只能选一件。 开始我对数组val的每一个元素,算出其价值与天数之比,将每一种课内,比值最大的选出来,这样每种课就只有一个选择,从而转化为01背包,但是提交之后WA了,于是我改用分组背包的标准解法,即for 所有的组k for v=V..0 for 所有的i属于组k f[v]=max{f[v],f[v-c[i]]+w[i]} 这样的确能够AC,但是我想知道为什么第一种方法不可行 下面分别是第一种和第二... 阅读全文
posted @ 2012-07-26 10:37 等待电子的砹 阅读(462) 评论(1) 推荐(0) 编辑
摘要:这是一道二维费用的背包问题,将dp多开一维,略修改一下状态转移方程即可,即dp[j][k]=get_max( dp[j-1][k-cost[i]]+value[i],dp[j][k]) 另外,这道题中,加注释的部分是WA了许多次后参考其他人的解题报告后加上的,暂时还没弄清楚为什么要这样做,这应该是背包的初始化的问题,应该要注意细节,问题留在这里,解决之后再修改解题报告。#include<stdio.h>#include<string.h>#define INF 10000000#define MAX_DVD_AMOUNT 110#define MAX_L 1100int 阅读全文
posted @ 2012-07-26 09:29 等待电子的砹 阅读(648) 评论(0) 推荐(0) 编辑
摘要:这是一道简单的多重背包问题,思路就是将多重背包转换为01背包,这道题由于我的函数 mkpackage()没有写对,导致在这道题上卡了很久。这种使用二进制思想划分物品的思路还需要理解,这一点非常重要。#include<stdio.h>#include<string.h>#define MAX_CASH_KIND 100#define MAX_DP_SPACE 100005#define MAX_STACK_SPACE 100001int get_max(int ,int ),top=0,stk[MAX_STACK_SPACE];void mkpackage(int,int 阅读全文
posted @ 2012-07-25 22:14 等待电子的砹 阅读(176) 评论(0) 推荐(0) 编辑
摘要:一道简单的完全背包,第一次的思路是正确的,但是由于疏忽,竟然将数组dp全部赋值为0,导致结果一直是0,进而怀疑自己的思路,于是走了许多弯路,后来才偶然发现应该将初值赋为无穷大(因为是求最小值),又犯了一次低级错误,下次应该注意!状态转移方程:dp[j]=get_min( dp[j],dp[j-wgh_coins[i]]+val_coins[i])由于是完全背包,所以第二重循环应该顺序而不是逆序。另外,dp[0]的初值为0,注意边界条件:当i=1,j=wgh_coins[i]时,方程为dp[j]=get_min(dp[j],dp[0]+val_coins[i]),只有dp[0]=0时,才能得出正 阅读全文
posted @ 2012-07-25 19:40 等待电子的砹 阅读(245) 评论(0) 推荐(0) 编辑