您的位置:首页 > 其它

动态规划,背包问题的解题思路

2014-09-09 20:52 232 查看
01背包问题:

        有n种物品,每种只有一个。第i种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品总体积不超过C的前提下重量尽可能的大。

1<=n<=100,1<=Vi<=C<=10000,1<=Wi<=10^6。

      解题思路:定义一个二维数组,第一维i为总共的物品数量,第二维j为剩余体积数量。每一维都尝试把所有的装进去,然后多余的空间装上一维的能装下的体积。直到最后一维,d[ i ][ j ]最大的那个即为Wi最大的那个。(必须倒着装)。

具体实现代码如下:

<span style="font-size:14px;">for(int i=n;i>=1;i--)//因为后面会出现i>n的情况,所以定义时数组要开大一位,超过n初始化为0,且只能逆序,正序会有d[-1]出现
for(int j=0;j<=c;j++)
{
d[i][j]=(i==n?0:d[i+1][j])//给它赋值前一位的数值,因为这一步的存在,所以可以用一维数组而不是二维
if(j>=V[i])  d[i][[j]=max(d[i][j],d[i][j-V[i]]+Wi)//对比一下当使用空间相等时,用剩V[i]空间的值加Wi之后是
//否比当前大,大的话就替换。
}

</span>


一位数组版本:

<span style="font-size:14px;">memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
cin>>V>>W;
for(int j=C;j>=0;j--)
{
if(j>=V)  f[j]= max(f[j],f[j-V]+W)
}
}//功能完全一样,思路完全一样
只是两种方法输出的方式会有差异。
</span>


A - 数塔

在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:

有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?



已经告诉你了,这是个DP的题目,你能AC吗?
 

Input

输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。

 

Output

对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。

 

Sample Input

 1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

 

Sample Output

 30

#include <iostream>
using namespace std;
const int N=102;
int shuta

;

int main()
{
int C;
cin>>C;
while(C--)
{
int n;
cin>>n;

for(int i=0;i<n;i++)
for(int j=0;j<=i;j++)
{
scanf("%d",&shuta[i][j]);
}

for(i=n-1;i>0;i--)
{
for(int j=0;j<i;j++)
{
if(shuta[i-1][j]+shuta[i][j]>shuta[i-1][j]+shuta[i][j+1])
shuta[i-1][j]+=shuta[i][j];
else
shuta[i-1][j]+=shuta[i][j+1];
}
}
cout<<shuta[0][0]<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划