题目链接: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. SQLite详解

    一.新建SQLite操作类(继承SQLiteOpenHelper) public class SQLiteTest extends SQLiteOpenHelper { final static St ...

  2. java 用socket制作一个简易多人聊天室

    代码: 服务器端Server import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{ ...

  3. 运行html,css,js好的软件

    WebStorm: http://pan.baidu.com/s/1eQF81Tw

  4. PowerShell调用jira rest api实现对个人提交bug数的统计

    通过PowerShell的invoke-webrequest和net.client联合实现个人指定项目jira提交数的统计,其中涉及到了JSON对象的提交,代码如下: $content = @{use ...

  5. CentOS 修改线程数限制等(limits.conf)

    修改/etc/security/limits.conf,例如启动程序的用户为webadmin,则添加以下配置: webadmin - nofile 65536 webadmin - nproc 655 ...

  6. java提高篇---HashTable

    在java中与有两个类都提供了一个多种用途的hashTable机制,他们都可以将可以key和value结合起来构成键值对通过put(key,value)方法保存起来,然后通过get(key)方法获取相 ...

  7. centOS6.5安装SUN-jdk7

    一.下载SUN-JDK1.7.tar.gz文件他 地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1 ...

  8. 微信支付:redirect-uri参数错误 的解决办法

    redirect_url参数错误: 报这个错误,说明你的公众号后台授权设置有问题(一般有两处) 一:检查授权目录 答:支付授权目录是网站发起请求的页面所在目录,并且必须是能通过url地址访问的(与真实 ...

  9. Android Handler Message总结

    http://blog.csdn.net/caesardadi/article/details/8473777 当应用程序启动时,会开启一个主线程(也就是UI线程),由她来管理UI,监听用户点击,来响 ...

  10. 转载 WebBrowser介绍——Javascript与C++互操作

    注:本文来自于 http://www.cnblogs.com/lucc/archive/2010/11/24/1886087.html WebBrowser控件是Microsoft提供的一个用于网页浏 ...