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
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':' ');
}
}
全部代码:
#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));
}
}
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;
}