PAT甲级1068 Find More Coins (30分)|C++实现

一、题目描述

原题链接
在这里插入图片描述

Input Specification:

在这里插入图片描述

​​Output Specification:

在这里插入图片描述

Sample Input 1:

8 9
5 9 8 7 2 3 4 1

Sample Output 1:

1 3 5

Sample Input 2:

4 8
7 2 4 3

Sample Output 2:

No Solution

二、解题思路

01背包问题,是动态规划问题,由于笔者对这方面的知识掌握得还不是很到位,建议大家去翻翻《算法笔记》中关于背包问题的讲述。

三、AC代码

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn = 10010;
const int maxv = 110;
int w[maxn], dp[maxv] = {
    
    0};  //w[i]为钱币的价值
bool choice[maxn][maxv], flag[maxn];
bool cmp(int a, int b) 
{
    
    return a > b; }//从大到小排序
int main() 
{
    
    
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
    sort(w + 1, w + n + 1, cmp);  //逆序排列
    for(int i = 1; i <= n; i++) 
    {
    
    
        for(int v = m; v >= w[i]; v--) 
        {
    
    
          	dp[v] = max(dp[v], dp[v-w[i]]+w[i]);    //状态转移方程
            if(dp[v] == dp[v-w[i]]+w[i])
              choice[i][v] = 1;
          	else
              choice[i][v] = 0;
        }
    }
    if(dp[m] != m) printf("No Solution");  //无解
    else 
    {
    
    
        //记录最优路径
        int k = n, num = 0, v = m;
        while(k >= 0) 
        {
    
    
            if(choice[k][v] == 1) 
            {
    
    
                flag[k] = true;
                v -= w[k];
                num++;
            }
            else flag[k] = false;
            k--;
        }
        //输出方案
        for(int i = n; i >= 1; i--) 
        {
    
    
            if(flag[i] == true) 
            {
    
    
                printf("%d", w[i]);
                num--;
                if(num > 0) printf(" ");
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42393947/article/details/108706749