• uva 674 Coin Change


    DP(DAG上的DP)

    题意:给你一个目标金额n,有5种硬币50,25,10,5,1,每种硬币无限个,用这些硬币构成这个目标金额n,有多少种不同的构建方法

    看做一个有向图处理:好像11能减去5得到6,那么有向边11--->6,同样11减10可以得到1,那么有有向边11--->1

    其实其他就是问n到0有多少条不同的路径。

    下面是注意处理的问题

    好像6,1+5和5+1是一样的只能算为一种情况。没了防止这种情况我们采用减序构建,好像5511是唯一一种它是减序的,5151这些就不是了

    这样做就不会重复,但是有可能漏掉,所以要记录前驱用的是哪一种硬币

    这样做不仅能防止重复还能防止遗漏,具体看代码

    另外一点,即便是正确的代码,任然可能TLE,为什么呢?因为是多组数据。这题虽然是多组数据,但某些数据的n比较大,它运行一遍后很多比n小的数据也已经计算出来了(这是必须的,因为DP本身符合最优子结构,必须知道子问题的最优解才能构造出原问题的最优解)。所以每组数据之前不要都将dp清为-1,每次都清的话相当于每次都要重头来过。另外数据中可能重复测试同一个数据,这不算坑,这其实是考察了到底明不明白这个问题的本质

    #include <cstdio>
    #include <cstring>
    #define N 7500
    const int m[10]={0,50,25,10,5,1};
    int dp[N][10];
    
    void dfs(int n , int p)
    {
        if(dp[n][p]!=-1)
            return ;
        dp[n][p]=0;
        for(int i=p; i<=5; i++)
        {
            if(n-m[i]>=0)
            {
                dfs(n-m[i] , i);
                dp[n][p]+=dp[n-m[i]][i];
            }
        }
        return ;
    }
    int main()
    {
        int n;
        memset(dp,-1,sizeof(dp));
        while(scanf("%d",&n)!=EOF)
        {
            for(int i=1; i<=5; i++)
                dp[0][i]=1;
            dfs(n,1);
            printf("%d\n",dp[n][1]);
        }
        return 0;
    }
  • 相关阅读:
    主页面
    EasyUI写的登录界面
    SpringMVC学习笔记二第一个小的程序
    springmvc学习笔记一框架的理解
    mybitis学习笔记
    cheng gong de daima
    JQuery中如何使用事件来出发Ajax
    按照用户名和角色查询用户liferay
    在liferay中如何使用Ajax的请求
    [奇葩说]
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2832968.html
Copyright © 2020-2023  润新知