PAT (Advanced) 1068. Find More Coins (30)

原题:1068. Find More Coins (30)



解题思路:

一开始想用搜索+回溯来做,但发现最后一个样例过不去,也想不出该怎么剪枝,就考虑其他方法了。

仔细分析一下就是一个01背包问题,只不过物品质量和价值比为1:1,求解就简单了。

如果最后结果dp[n][m]不等于价值量,也就是无解了。

第二个问题是求最小解,一开始我是从小到大放,但是无法求出最小解,就试着从大到小放硬币,发现可以完成任务。


代码如下:

#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 10000 + 5;
int coin[maxn], n, m;
int dp[maxn][101];
int choice[maxn][101];
vector<int> ans;
bool cmp(int a, int b) //从大到小
{
    return a > b;
}

void save(int n, int m) //一开始用来递归打印的函数,现在干脆直接拿来存答案了
{
    if(choice[n][m] == -1) return;
    else if(choice[n][m] == 0) save(n-1, m);
    else if(choice[n][m] == 1)
    {
        save(n-1, m-coin[n]);
        ans.push_back(coin[n]);
    }
}


int main()
{
    while(scanf("%d%d", &n, &m) == 2)
    {
        for(int i = 1; i <= n; i++) scanf("%d", &coin[i]);
        sort(coin+1, coin + n + 1, cmp);

        for(int i = 0; i <= n; i++) dp[i][0] = 0;
        for(int i = 0; i <= m; i++) dp[0][i] = 0;
        choice[0][0] = -1;
        for(int i = 1; i <= n; i++)
        {
            for(int j = m; j >= 1; j--)
                if(j >= coin[i])
                {
                    if(dp[i-1][j] > dp[i-1][j-coin[i]] + coin[i])//如果算上当前硬币小于不算的情况,就不选
                    {
                        dp[i][j] = dp[i-1][j];
                        choice[i][j] = 0;
                    }
                    else //算上大于等于就选当前硬币
                    {
                        dp[i][j] = dp[i-1][j-coin[i]] + coin[i];
                        choice[i][j] = 1;
                    }

                }
                else
                {
                    dp[i][j] = dp[i-1][j];
                    choice[i][j] = 0;
                }
        }


        if(dp[n][m] == m)
        {
            ans.clear();
            save(n, m);
            for(int i = ans.size()-1; i >= 0; i--)
                if(i == ans.size()-1) printf("%d", ans[i]);
                else printf(" %d", ans[i]);
            printf("\n");
        }
        else printf("No Solution\n");
    }
    return 0;
}

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值