PAT (Advanced Level) 1068. Find More Coins (30)

01背包路径输出。

保证字典序最小:从大到小做背包。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;

const int maxn=100+10;
bool dp[maxn*maxn][maxn];
int a[maxn*maxn];
int n,k;
vector<int>ans;
struct Path
{
    int r,c;
}p[maxn*maxn][maxn];

bool cmp(const int &a,const int &b)
{
    return a>b;
}

int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(a+1,a+1+n,cmp);
    memset(dp,0,sizeof dp);
    for(int i=0;i<=n;i++)
        for(int j=0;j<=k;j++)
            p[i][j].r=p[i][j].c=-1;
    dp[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=k;j++)
        {
            if(dp[i-1][j]==0) continue;
            if(j+a[i]>k) continue;
            dp[i][j+a[i]]=1;
            p[i][j+a[i]].r=i-1;
            p[i][j+a[i]].c =j;
        }
        for(int j=0;j<=k;j++)
        {
            if(dp[i-1][j]==1&&dp[i][j]==0)
            {
                p[i][j].r=p[i-1][j].r;
                p[i][j].c=p[i-1][j].c;
            }
            dp[i][j]=max(dp[i][j],dp[i-1][j]);
        }
    }

    if(dp[n][k]==0) printf("No Solution\n");
    else
    {
        int nowr=n,nowc=k;
        while(1)
        {
            ans.push_back(nowc-p[nowr][nowc].c);
            int tmpr=nowr,tmpc=nowc;
            nowc=p[tmpr][tmpc].c;
            nowr=p[tmpr][tmpc].r;
            if(nowc==0) break;
        }
        for(int i=0;i<ans.size();i++)
        {
            printf("%d",ans[i]);
            if(i<ans.size()-1) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

 

posted @ 2016-07-01 14:47  Fighting_Heart  阅读(137)  评论(0编辑  收藏  举报