上一页 1 ··· 8 9 10 11 12 13 14 15 16 ··· 18 下一页
题意:一棵树,有n个结点,每个结点有w[i]个bug,有p[i]的brain。我从1号结点开始走,带着m个战士。1个战士可以消灭20个bugs如果我把某个结点的所有bug都消灭了我就能得到那个结点的brain。如果想攻击当前结点,那么必须先攻击了它的父结点(1号点除外)。注意:1. 其中当你攻占了当前结点,你可以分派人手,走向几个不同的子结点,去攻占更多。也就是说,不是单一的路径。2. 如果输入0个战士直接输出0,即使该洞bug数为0,要获得该洞brain值,也需要至少一人经过该洞穴(可以不停留),而用dfs计算会出现正值。本题数据小,节点100,如果数据大了尽量不要用vector,可能会超时 Read More
posted @ 2012-08-14 15:06 To be an ACMan Views(204) Comments(0) Diggs(0)
题意:给定一个面值Price, 1美分的硬币有c[1]个, 5美分的硬币有c[2]个,10美分的硬币有c[3]个,25美分的硬币有c[4]个,求用给定的硬币兑换Price面额的钱,并且要求硬币数最多,求出每种硬币得用多少个.题目关键:要保存路径,然后输出。我们用pre[j]表示最新更新j的那个状态,j-w[i]等状态,因为多重背包里有二进制压缩,有些状态转移1次纸币数量不一定只加了1,所以用num[j]表示状态转移到j加了多少张纸币。路径输出处理:memset(ans,0,sizeof(ans));for(i=m;i!=0;i=pre[i]) //用pre[j]把路径逆着走一边{ in... Read More
posted @ 2012-08-14 14:06 To be an ACMan Views(378) Comments(0) Diggs(0)
题意:有钱sum,给出n组选择,每种选择有m个物品w,要买物品先必须买盒子,物品价格为w[i],价值p[i]。然后给出每种选择的一些物品的价格还有价值求取得最大值。物品依赖于盒子。按照背包九讲的做法:先对每组选择里的所有物品进行0-1背包处理,但背包容量为(总容量-盒子容量);然后跟上一组的状态比较来决定这一组选择 是选还是不选,取其中的较大值。用dp[i][j]表示第i组背包容量为j时的最大价值。在转移状态之前当前组选择的初始化:for(j=0;j<q;j++)//q表示盒子的价格 dp[i][j]=-INF;//当钱<盒子价格时,无价值,注意不要赋值为0, 这题有 重量为0,但 Read More
posted @ 2012-08-14 13:09 To be an ACMan Views(202) Comments(0) Diggs(0)
题意:给你钱的价值和数量,求能在价值m以内能够拼出多少种钱数。View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;bool dp[120003];int w[101],c[101];int main(){ int n, m, i, j; while(~scanf("%d%d",&n,&m)) { if(!m&&!n)break; for(i=1;i<=n;i++) scanf(" Read More
posted @ 2012-08-14 09:51 To be an ACMan Views(190) Comments(0) Diggs(0)
题意:说有一个人去买m元的东西,有n种钱币,没种钱币的面额是w[i],个数是C[i],售货员每种钱币有无数多个。现在这个人想让交易的钱个数最少,即找回的和付出钱的张数,最少。多重背包+完全背包。买家:多重背包;售货员:完全背包;开两个数组,分别计算出买家,售货员每个面额的最少张数。最重要的是上界的处理。可以注意到,上界为maxw*maxw+m(maxw最大面额的纸币),也就是24400元。(网上的证明)证明如下:如果买家的付款数大于了maxw*maxw+m,即付硬币的数目大于了maxw,根据鸽笼原理,至少有两个的和对maxw取模的值相等,也就是说,这部分硬币能够用更少的maxw来代替。证毕。真 Read More
posted @ 2012-08-14 09:32 To be an ACMan Views(1084) Comments(0) Diggs(0)
题意:给你一些钱去投资,现在有n种股票,每种股票都有一个价值和年收益,问你如何投资在d年后的最大收益并且股票的价值都是1000的倍数,预处理:对每个价值除以1000,减少内存。完全背包,每投资一年,你的钱会变多,即背包总容量会变大。对每一年的资金进行完全背包,然后更新背包总容量,d次循环后得出答案dp上界:每次投资最多获利本金的10%,所以先写个程序计算出dp上界 1000000.0*pow(1.1,40)/1000=45259View Code #include<stdio.h>#include<string.h>#include<algorithm>us Read More
posted @ 2012-08-13 22:59 To be an ACMan Views(189) Comments(0) Diggs(0)
题意:给6个纸币面额,求出用最少的这6个纸币凑出1-100的面值,求这1-100需要的纸币数种的最大值。解题思路:2个完全背包。注意点:(1)可以相加也可以想减,(2)注意上限,考虑极端数据1 95 96 97 98 99。貌似计算出48次数最多,大概估计不超过30次,所以dp开30*100,如果懒得考虑,直接开100*100。AC代码:View Code #include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define maxn 3000#define INF Read More
posted @ 2012-08-13 22:24 To be an ACMan Views(188) Comments(0) Diggs(0)
经典混合背包 题目给了很多类别的物品。用数组dp[i][j],表示第i组,时间为j时的快乐值。每得到一组工作就进行一次DP,所以dp[i]为第i组的结果。 第一类,至少选一项,即必须要选,那么在开始时,对于这一组的dp的初值,应该全部赋为负无穷,这样才能保证不会出现都不选的情况。状态转移方程:dp[i][j]=max(dp[i][j],max(dp[i][j-w[x]]+p[x],dp[i-1][j-w[x]]+p[x]));dp[i][j]: 是不选择当前工作;dp[i-1][j-w[x]]+p[x]: 第一次在本组中选物品,由于开始将该组dp赋为了负无穷,所以第一次取时,必须由上一组的结. Read More
posted @ 2012-08-13 20:58 To be an ACMan Views(1040) Comments(3) Diggs(3)
注意至少取一个,仔细分析一下,此时光靠一个一维数组是不可以完成状态转移的,必须用二维数组或两个一维数组(滚动数组)。建议多用二维数组,二维数组比较好理解,不容易出错,除非数据量太大,二维开不下。当然,如果对状态转移理解的比较深刻可以尝试着写成滚动数组。先讲一讲二维数组的做法:dp[i][j]表示进行到了第i组容量为j所装载的最大价值。则dp[i][j]这个状态必须从dp[i-1][j-w[x]]+p[x] (选了第1个第i组的物品),dp[i][j-w[x]]+p[x](已经选过第i组的物品,这次又选了第i组的物品),dp[i][j](不选这个物品);所以状态转移方程为:dp[i][j]=ma Read More
posted @ 2012-08-13 19:21 To be an ACMan Views(264) Comments(0) Diggs(0)
题意:给了n个边,要求每条都用上,组成一个三角形,求三角形面积最大值的100倍(取整数);分析:我们可以开个二维数组dp[i][j]来记录三角形的两条边的长度i,j,那么另一条边就是总长度减去i和j。疑问:判定能构成三角形的条件,设p为三角形的半周长,a+b>c 两边同时加上c 则 2*p>2*c即 p>c,同理p>a,p>b。由海伦公式S=sqrt(p*(p-a)*(p-b)*(p*c))也可以得出这结论。View Code #include<stdio.h>#include<string.h>#include<math.h> Read More
posted @ 2012-08-12 23:01 To be an ACMan Views(215) Comments(0) Diggs(0)
上一页 1 ··· 8 9 10 11 12 13 14 15 16 ··· 18 下一页