L3-001. 凑零钱

L3-001. 凑零钱

题目链接:https://www.patest.cn/contests/gplt/L3-001

动态规划

这道题一看就知道应该用背包思想来做,不过想了好久没什么思路(dp实在是渣),最后还是鼓捣出来了ac代码QAQ,细节加了注释。

代码如下:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<stack>
 5 using namespace std;
 6 const int INF=-0x3fffffff;
 7 stack<int>s;
 8 int dp[101],pre[101],a[10001];
 9 int main(void){
10     //freopen("in.txt","r",stdin);
11     for(int i=0;i<=100;++i){
12         dp[i]=INF;
13         pre[i]=-1;
14     }
15     dp[0]=0;
16     int n,m;
17     scanf("%d%d",&n,&m);
18     for(int i=1;i<=n;++i)
19         scanf("%d",&a[i]);
20     sort(&a[1],&a[1]+n);
21     for(int i=1;i<=n;++i){
22         for(int j=m;j>=a[i];--j){
23             if(dp[j]<=dp[j-a[i]]+1){
/*加等号是因为在硬币个数相同的情况下,若其中一枚更大,相对另一枚更小,从而使得字典序最小*/
24 dp[j]=dp[j-a[i]]+1; 25 pre[j]=j-a[i];/*记录路径*/ 26 } 27 } 28 } 29 if(dp[m]>0){ 30 int k=m; 31 while(pre[k]){ 32 s.push(k-pre[k]); 33 k=pre[k]; 34 } 35 printf("%d",k); 36 while(!s.empty()){ 37 printf(" %d",s.top()); 38 s.pop(); 39 } 40 printf(" "); 41 }else printf("No Solution "); 42 return 0; 43 }

如有更好的方法,望不吝赐教!!

原文地址:https://www.cnblogs.com/barrier/p/5553652.html