1068 Find More Coins (01背包求具体方案)

题目大意:给定一组数字,选取若干个数,使其和为m,如果有多个解,输出字典序最小的解。

思路:由于需要输出最小字典序,故我们可以先将物品从小到大排序,然后我们从后往前进行01背包的求解,求最大价值。如果所求的最大价值不等于m,则为No Solution。否则,我们将从体积为m进行从前往后的回溯,如果当前的体积为后一个物品的体积转移而来,则方案中必然选取了该物品,这时我们输出该物品的体积,并使体积减去该物品的体积。以此类推直到输出该方案的所有物品。

代码:

#include
using namespace std;
int v[100005];
int dp[100005][110];
int main(){
    int n,m;cin>>n>>m;
    for(int i=0;i>v[i];
    sort(v,v+n);
    for(int i=n-1;i>=0;i--){//输出最小字典序路径,故从后往前推,使最后推出的最优结点为前面的结点
        for(int j=0;j<=m;j++){
            dp[i][j]=dp[i+1][j];
            if(j>=v[i])
            dp[i][j]=max(dp[i][j],dp[i+1][j-v[i]]+v[i]);
        }
    }
    if(dp[0][m]!=m){
        cout<<"No Solution";
        return 0;
    }
    int j=m;
    int flag=0;
    for(int i=0;i=v[i]&&dp[i][j]==dp[i+1][j-v[i]]+v[i]){//该结点是由后一个结点转移过来的
            if(flag)cout<<' ';
            cout<

你可能感兴趣的:(算法,数据结构)