Timus 1244

简单的01背包,关键是找路径,通过此题对01背包找路径有了更深的认识了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
int res[100010],nPath[100010],father[100010],data[110];
int work(int goal,int n)
{
    int i,j;
        memset(res,0,sizeof(res));
    memset(nPath,0,sizeof(nPath));
    memset(father,0,sizeof(father));
    res[0]=1; nPath[0]=1;
    for(i=1;i<=n;i++)
        for(j=goal;j>=data[i];j--)
            if(res[j-data[i]])
            {
                res[j]=1;  
                if(!father[j]) father[j]=i;
                nPath[j]+=nPath[j-data[i]];
            }

    if(res[goal]==0 || goal==0) return 0;
    if(nPath[goal]>1) return -1;
    return 1;
}
int GetPath(int goal,int n)
{
    stack <int> S;
    while(goal)
    {
        S.push(father[goal]);
        goal=goal-data[father[goal]];
    }
    printf("%d",S.top()); S.pop();
    while(!S.empty())
    {
        printf(" %d",S.top()); S.pop();
    }
    printf("\n");
    return 0;
}
int main()
{
    int i,n,goal,r,sum;
    while(scanf("%d",&goal)!=EOF)
    {
        scanf("%d",&n);
        sum=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&data[i]);
            sum+=data[i];
        }
        r=work(sum-goal,n);
        if(r==0)
        {
            printf("0\n");
        }
        else if(r==-1)
        {
            printf("-1\n");
        }
        else
        {
            GetPath(sum-goal,n);
        }
    }
    return 0;
}
posted @ 2012-05-23 10:22  书山有路,学海无涯  阅读(152)  评论(0编辑  收藏  举报