题意:给你一些钱去投资,现在有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)