【思路】
01背包+路径输出。
用d[][]记录[][]可转移的数目,>=2则输出-1,0输出0,否则输出路径。对于路径可以写一个递归过程print完成。
本题的数据着实有些坑,需要注意的有数组的范围,使用LL。题目中为什么没有交待?
【代码】
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 const int maxn = 300+10; 6 7 typedef long long LL; 8 LL d[maxn][200100]; 9 LL a[maxn]; 10 LL n,W; 11 12 void print(LL n,LL w) { 13 if(n<=0 || !w) return ; 14 if(d[n-1][w]) { 15 print(n-1,w); 16 } 17 else{ 18 print(n-1,w-a[n]); 19 cout<<n<<" "; 20 } 21 } 22 23 int main() { 24 ios::sync_with_stdio(false); 25 cin>>W>>n; 26 LL sum=0; 27 for(int i=1;i<=n;i++) cin>>a[i] , sum+=a[i]; 28 W=sum-W; 29 for(int i=0;i<=n;i++) d[i][0]=1; 30 for(int i=1;i<=n;i++) 31 for(int j=0;j<=W;j++) 32 { 33 d[i][j] = d[i-1][j]+d[i-1][j-a[i]]; 34 } 35 36 if(!d[n][W]) cout<<0; 37 else 38 if(d[n][W]>=2) cout<<-1; 39 else { 40 print(n,W); 41 } 42 return 0; 43 }
时间: 2024-10-25 08:25:53