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