题目链接:http://poj.org/problem?id=2063

  今天果然是卡题的一天。白天被hdu那道01背包的变形卡到现在还没想通就不说了,然后晚上又被这道有个不大也不小的坑的完全背包卡了好久。这题主要是说让你选择不同的债券(每种债券的费用和年利率的属性),然后n年后使得本金最大,如果仅仅是问一年的话就是个裸完全背包的题了,不过它是n年,每年得到的总利息都会加入到本金中变为下一年的本金,知道了这个后就很好处理了,在这道题里每年变化的本金就是背包容量,然后债券那两个属性就是物品的费用(or体积)和价值(or重量)。

  一开始我快速码好后提交结果各种MLE,TLE,当注意到每种债券的费用都是1000的倍数时我改了下,大概主函数如下:

 while(y--){
memset(dp,,sizeof(dp));
for(i=; i<=d; ++i)
for(j=cost[i]; j<=capital; j+=)
dp[j]= max(dp[j],dp[j-cost[i]]+value[i]);
capital+= dp[capital/*];
}

  提交后还是TLE,我就奇怪了,虽说和标程的常规方法不同,但初步分析下复杂度应该是一样的啊,j 每次都是1000地递增的,后来经过用标程提交几番痛苦的摸索后终于知道TLE的根本原因是memset函数!因为我的dp数组开到了 int dp[7000006] 这么大,而y的上限是40,相乘后就是280000000,1s根本没法承受!本作为辅助的步奏却大大超过了主算法的时间,所以我干脆用for手动清零算了,改成这样:

 //    memset(dp,0,sizeof(dp));
for(j=; j<=capital; j+=)
dp[j]= ;

  然后华丽地RE了,看来数组dp[7000006]竟然还不够大,然后我稍微开大了一点点,就MLE了,看来这个是30000KB的临界值了(后来我才发现这题的本金即背包容量会达到 5kw!即使数组勉勉强强开得下,也绝对远远超过了大多数题目的内存限制),没办法了,即使我这种方法的技巧性再强,还是会被各种TLE,MLE,RE卡死,看来真的需要常常规规的去做了。需要把债券的费用和本金缩小1000倍,这样子背包容量的 j 循环就可以连续的了,数组的空利用率也大大提交(T.T 和我上面的做法相比就可以看出来)。这样做的话maxn只需要开到50000即可,实际放大后就是5kw,如果硬要把maxn开到百万级别以上的话,memset就不能用,必须手动清零,否则时间就会浪费在为数组那些实际上不会用上的空间进行清零,即使memset按字节来处理也忍受不了千万级别的1s时限,基于各种修改过后的代码如下:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
using namespace std;
const int maxn= ; int dp[maxn+], cost[],value[]; int main(){
int t,capital,y,d,i,j,tmp;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&capital,&y,&d);
for(i=; i<=d; cost[i]/= , ++i)
scanf("%d%d",cost+i,value+i);
double b = clock();
while(y--){
// memset(dp,0,sizeof(dp)); 这个没有错,但上面的 maxn一定不能太大!
tmp= capital/;
for(j=; j<=tmp; ++j)
dp[j]= ;
for(i=; i<=d; ++i)
for(j=cost[i]; j<=tmp; ++j)
dp[j]= max(dp[j],dp[j-cost[i]]+value[i]);
capital+= dp[tmp];
}
double c = clock();
// printf("%.f\n",c-b);
printf("%d\n",capital);
}
return ;
}

  交之,63ms Accepted。

  从这道题中我得到的教训就是为了不用推倒重来而使用上那一点点小技巧(即j+=1000),却使数组空间大大浪费掉(不是么,1/1000的利用率 T.T),然后还带来了MLE or RE的不可避免的风险;第二个学到的就是,memset函数也有可能是TLE的根源,要看清数组会有多大,所以以后当TLE时检查了scanf里有没漏 & 取址符或long long的读入有误,或者少了个EOF,或者其他等等等等非算法问题造成的超时后,不妨看看是否有可能数组太大,memset会不会做了多余的工作(为数组实际用不上的空间进行操作)等等。

POJ 2063 Investment 完全背包的更多相关文章

  1. POJ 2063 Investment (完全背包)

    A - Investment Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Subm ...

  2. POJ 2063 Investment 滚动数组+完全背包

    题目链接: http://poj.org/problem?id=2063 题意: 你现在有现金m元,你要做n年的存款投资,给你k种投资方式,每种需要现金vi元,能获得xi元的理论,一年到期后你要利用拿 ...

  3. poj 2063 Investment ( zoj 2224 Investment ) 完全背包

    传送门: POJ:http://poj.org/problem?id=2063 ZOJ:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problem ...

  4. poj 2063 Investmen 完全背包

    这个题的想法不难,两个点: 1 是完全背包 2 是考虑/1000,降低复杂度   但是提交的时候反复的wa,最后找问题原来是dp开小了,可是dp本来开1005,后来开到100030过了.哎,如果没有时 ...

  5. [POJ 2063] Investment (动态规划)

    题目链接:http://poj.org/problem?id=2063 题意:银行每年提供d种债券,每种债券需要付出p[i]块钱,然后一年的收入是v[i],到期后我们把本金+收入取出来作为下一年度本金 ...

  6. poj 2063 Investment

    题意:给定一个初始资金capital,然后给定d种投资方案,每种投资方案中有投资额value[i](是1000的倍数)和利息interest[i],每年的投资就可以拿到全部利息,然后累加起来继续投资利 ...

  7. 专题复习--背包问题+例题(HDU 2602 、POJ 2063、 POJ 1787、 UVA 674 、UVA 147)

    *注 虽然没什么人看我的博客但我还是要认认真真写给自己看 背包问题应用场景给定 n 种物品和一个背包.物品 i 的重量是 w i ,其价值为 v i ,背包的容量为C.应该如何选择装入背包中的物品,使 ...

  8. poj 2063完全背包

    题意:给出总资金和投资年份 ,n个股票 给出股票价格和其一年的利润.问如何选择能获得最大利润. 思路:股票可以重复选择,完全背包问题,完全背包也是从01背包衍生而行的,其主要区别在于中间那层循环的次序 ...

  9. POJ 1155 (树形DP+背包+优化)

    题目链接: http://poj.org/problem?id=1155 题目大意:电视台转播节目.对于每个根,其子结点可能是用户,也可能是中转站.但是用户肯定是叶子结点.传到中转站或是用户都要花钱, ...

随机推荐

  1. ACM第四站————最小生成树(克鲁斯卡尔算法)

    都是生成最小生成树,库鲁斯卡尔算法与普里姆算法的不同之处在于——库鲁斯卡尔算法的思想是以边为主,找权值最小的边生成最小生成树. 主要在于构建边集数组,然后不断寻找最小的边. 同样的题目:最小生成树 题 ...

  2. HDU 2067:小兔的棋盘

    小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  3. Maximum Value(哈希)

    B. Maximum Value time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  4. VRRP配置与维护手册-1

    http://www.gpxz.com/diannao/hulianwang/80526.html 一  VRRP简介< xmlnamespace prefix ="o" n ...

  5. C语言typeof详解 offsetof

    http://blog.chinaunix.net/uid-28458801-id-4200573.html 前言:    typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常 ...

  6. Linux Source命令及脚本的执行方式解析

    转 http://www.51testing.com/html/38/225738-206878.html 当我修改了/etc/profile文件,我想让它立刻生效,而不用重新登录:这时就想到用sou ...

  7. 《JAVA与模式》之策略模式

    <JAVA与模式>之策略模式 在阎宏博士的<JAVA与模式>一书中开头是这样描述策略(Strategy)模式的: 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法 ...

  8. 数据库SQL语句练习题5--9

    5. 查询Score表中成绩为85,86或88的记录. ,,) 6. 查询Student表中“95031”班或性别为“女”的同学记录. ' or ssex = '女' 7. 以Class降序查询Stu ...

  9. 如何查看PowerShell版本

    Click Start, click All Programs, click Accessories, click Windows PowerShell, and then click Windows ...

  10. How To Use RUN_PRODUCT In Oracle Forms

    Run_Product is used to run Oracle Reports (RDF/REP files) in Oracle Forms. It invokes one of the sup ...