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;

}

你可能感兴趣的:(IM)