硬币问题

硬币问题有可能是无解的

定义状态d[i] 从i减到0的最少使用的硬币数

可能会无解

下面是代码

//主要问题有:矩阵嵌套问题一开始调用solve(i)的i是怎么确定的?
//可以认为是任意一个点吗?
//可以认为是任意一个点?
//那么如何定义状态?
//状态的定义与实际的情况是有关的(有向边是从大到小还是从小到大),但无论怎么,最后的值应该是要打印的那一边的值
//因为这样才可以确定打印的时候的字典序
//当然上面的矩阵嵌套是保证有解的
//回到硬币问题上来
//这个问题不一定有解
//但最后的值必须是在s这边,不应该是在0那边
//所以有两种状态定义的方式:从i出发的最长路,终点到i的最长路
//但是这两种方式的定义又有一些区别(虽然在矩阵嵌套问题上并没有区别)
//从s出发的时候不一定是有解的
//递推可以使用的核心是,计算的时候需要使用的数据都已经全部得到了
#include<cstdio>
#include<algorithm>
using namespace std;

//定义状态,d[i]为选用最多的硬币,使得面值之和恰好为i
const int maxn = 150;

int S = 100;
int d[maxn];
int V[] = {2,3,5,7};
int vis[maxn];


int dp(int x)
{
    if(vis[x])
        return d[x];
    vis[x] = 1;
    d[x] = 1000;
    for(int i = 0;i < 4;i++)
    {
        if(x >= V[i])
        {
            d[x] = min(d[x],dp(x - V[i]) + 1);
        }
    }
    return d[x];
}
void print_ans(int x)
{
    for(int i = 0;i < V[i];i++)
    {
        if(d[x] == d[x - V[i]] + 1)
        {
            printf("%d ",V[i]);
            print_ans(x - V[i]);
            return ;
        }
    }
}



int main()
{
    d[0] = 0;
    vis[0] = 1;
    dp(S);
    print_ans(S);
    for(int i = 1;i <= S;i++)
    {
        d[i] = 1000;
        for(int j = 0;j < 4;j++)
        {
            if(i >= V[j])
            {
                //d[i] = max(d[i],d[i - V[j]] + 1);
                d[i] = min(d[i],d[i -V[j]] + 1);
            }
        }
    }



    return 0;
}

 

转载于:https://www.cnblogs.com/TorettoRui/p/10482455.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值