0-1背包的状态转移方程:
dp[i][j]=max(dp[i-1][j], dp[i-1][j-a[i]]+a[i]);
如果一个物品被选中那么:
dp[i][j]==dp[i-1][j-a[i]]+a[i]
dp[i][ans-a[i]]+a[i]==ans//ans初始值:dp[n][s]表示背包里没有确定物品编号的总体积
//所以可以输出选择物品的编号
int ans=dp[n][s];
for(int i=n;i>=1;i--)
{
if(ans>=a[i]&&ans==dp[i][ans-a[i]]+a[i])
{
ans-=a[i];
printf("%d%c",i,ans==0?'\n':' ');
}
}
//但是编号是从大到小的
//解决方法一:但是我们从a[n]开始读入数据,那么printf()中的i改成n-i+1就行了。
//解决方法二:用递归输出
全部代码:
#include<bits/stdc++.h>
using namespace std;
int a[105];
int dp[100][100]={0};
void dfs(int n, int s)
{
if(s==0)
return;
if(s<a[n])
{
dfs(n-1, s);
}
else
{
if(s==dp[n-1][s-a[n]]+a[n])
{
dfs(n-1, s-a[n]);
printf("%d ",n);
}
else
{
dfs(n-1, s);
}
}
}
int main()
{
int n, s;
scanf("%d%d",&n,&s);
for(int i=n;i>=1;i--)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=s;j++)
{
dp[i][j]=max(dp[i-1][j], (j>=a[i]?dp[i-1][j-a[i]]+a[i]:0));
}
}
//dfs(n, dp[n][s]);//递归输出
int ans=dp[n][s];
for(int i=n;i>=1;i--)
{
if(ans>=a[i]&&ans==dp[i][ans-a[i]]+a[i])
{
ans-=a[i];
printf("%d%c",n-i+1,ans==0?'\n':' ');
}
}
return 0;
}
dp专题 0-1背包输出具体的方案
最新推荐文章于 2024-11-07 12:00:23 发布