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;
}