Description
你有一个神奇的背包,他的容积是m(0<m<=80),只有你装满他,你才能拿走他,现在给你n(1<=n<=20)个物品Xi(Xi<=m),那么一共有几种方式,可以让你拿走背包?
Input
第一行 n,m
第二行 n个数字
Output
输出方案数
Sample Input
3 40 20 20 20
Sample Output
3
分析:
给出几种不同体积的物品,把背包装满,基础深搜题,思路比较简单,但是dfs接触不多,做出来比较困难
思路:
1.判断边界,正好装满,或者没装满超出范围,return;
2.对于每一种物品,装或不装,两个递归下去就可以了。
深搜模板:
void dfs(int step)
{
判断边界,返回
for(i=1;i<=n;i++) 尝试每一种可能
{
继续下一步dfs(step+1);
}
return;
}
参考其他人写出来的代码:
#include<stdio.h>
int n, m, a[30], ans;
void dfs(int v, int k)//v背包本层容量,k就是数组的下标
{
if ( v== 0)//判断边间,如果v等于0,那说明背包正好装满了,那么这是一种装法,所以ans++;
{
ans++;
return;//记得结束
}
if (v<0 || k>n)//如果要装进去的东西太多了或者所有东西都装进去了(本题必须要装满才能拿),都不满足
return;
dfs(v - a[k], k + 1);//放进一个a[k]的东西
dfs(v, k + 1);//不放
return;
}
int main()
{
while (scanf("%d%d", &n, &m)==2)
{
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
ans = 0;//初始化
dfs(m, 1);
printf("%d\n", ans);
}
return 0;}
啊,听了同学的讲解,发现可以用竟然可以用动态规划,背包思想做出来,真的是太厉害了呀
for(i=1;i<n;i++)
for(j=1;j<k;j++)
{
if(j<w[i]) f[i][j]=f[i-1][j];;
if(j==w[i]) f[i][j]=f[i-1][j]+1;
if(j>w[i])f[i][j]=f[i-1][j-w[i]];
}
2 3
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 0 | 0 | 0 |
2 | 0 | 1 | 1 | 1 | 1 |