金矿模型温习

            又从金矿模型开始了动态规划,感觉理解又深了一点吧,因为今天刷题不是很顺利,普通01背包很好应付,可是今天见的总是TLE,真是崩溃,同时也花费了大量时间在这上面,关于金矿模型的原文详见:http://blog.csdn.net/power721/article/details/4908401,里面也有参考代码。

           关于总结别人写的很详细了,就通过个人学习所得说一下我学习的时候感觉迷茫的地方。我在学DP的时候有一种感觉就是别人讲的看懂了,但是自己动手写程序时却感觉无从下手,但是经过仔细分析之后慢慢就感觉有点思路了,就拿这个最简单的01背包类型的金矿模型题目来说吧,首先我最先想到的方法是递归,这个写起来就比较简单了,类似求n阶乘的做法,第二就是一般方法,别人在讲解的时候都说从最后一个子结构开始向前推,可是具体应用到程序里面该怎样写呢?这是我在学习的时候也曾遇到的,那我的做法就是:先把别人的程序走一遍,慢慢理解。下面解决我上面的提问:我们可以用一个表示人数为i的s[i]数组来表示当前能得到的最大金币数,可以想象最后的s[maxpeople]就是所要求的答案,具体过程可以观察程序,我觉得这个没什么说了,还是神马都自己走一遍,下面附上关于金矿模型我理解的程序,有兴趣的可以拷到自己编译器里调试一下,看看其中的过程,以帮助理解:最后总结一句:几乎所有的01背包类型的DP转移方程都是上面所提到的转移方程。 

#include<cstdio>
using namespace std;
int max(int a,int b)
{
	if(a>b)
		return a;
	return b;
}
int main()
{
	int c[10002],w[10002];
	int n,v,i,j;
	while(scanf("%d%d",&v,&n)&&(v||n))
	{
		int s[10002]={0};
		for(i=1;i<=n;i++)
			scanf("%d%d",&c[i],&w[i]);
		for(i=1;i<=n;i++)
			for(j=v;j>=c[i];j--)
				s[j]=max(s[j],s[j-c[i]]+w[i]);
		printf("%d\n",s[v]);
	}
	return 0;

由于我理解的还不够深入,所以今天刷题时也遇到了种种困难,总是TLE,很是郁闷,明日计划:DP经典题型---单调子序列
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值