• POJ3181——DP(找钱3)——Dollar Dayz


    Description

    Farmer John goes to Dollar Days at The Cow Store and discovers an unlimited number of tools on sale. During his first visit, the tools are selling variously for $1, $2, and $3. Farmer John has exactly $5 to spend. He can buy 5 tools at $1 each or 1 tool at $3 and an additional 1 tool at $2. Of course, there are other combinations for a total of 5 different ways FJ can spend all his money on tools. Here they are: 

            1 @ US$3 + 1 @ US$2 
    1 @ US$3 + 2 @ US$1
    1 @ US$2 + 3 @ US$1
    2 @ US$2 + 1 @ US$1
    5 @ US$1
    Write a program than will compute the number of ways FJ can spend N dollars (1 <= N <= 1000) at The Cow Store for tools on sale with a cost of $1..$K (1 <= K <= 100).

    Input

    A single line with two space-separated integers: N and K.

    Output

    A single line with a single integer that is the number of unique ways FJ can spend his money.

    Sample Input

    5 3

    Sample Output

    5
    大意:仍然是找钱问题,不过用原来的方法发现数用unsigned long long 都存不下。。只能看成完全背包来做,分成两块
    以下来自ACM荣耀大神 传送门

    整数划分是把一个正整数 N 拆分成一组数相加并且等于 N 的问题.
    比如:
    6
    5 + 1 (序列)
    4 + 2, 4 + 1 + 1
    3 + 3, 3 + 2 + 1, 3 + 1 + 1 + 1
    2 + 2 + 2, 2 + 2 + 1 + 1, 2 + 1 + 1 + 1 + 1
    1 + 1 + 1 + 1 + 1 + 1

    假设F(N,M) 整数 N 的划分个数,其中 M 表示将 N 拆分后的序列中最大数

    考虑边界状态:
    M = 1 或者 N = 1 只有一个划分 既: F(1,1) = 1
    M = N : 等于把M - 1 的划分数加 1 既: F(N,N) = F(N,N-1) + 1 
    M > N: 按理说,N 划分后的序列中最大数是不会超过 N 的,所以 F(N,M ) = F(N,N)
    M < N: 这个是最常见的, 他应该是序列中最大数为 M-1 的划分和 N-M 的划分之和, 比如F(6,4),上面例子第三行, 他应该等于对整数 3 的划分, 然后加上 2 的划分(6-4) 所以 F(N,M) = F(N, M-1) + F(N-M,M)

    用动态规划来表示

     dp[n][m]= dp[n][m-1]+ dp[n-m][m]
               
               dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。
               则划分数可以分为两种情况:
     
               a. 划分中每个数都小于 m, 相当于每个数不大于 m- 1, 故
                  划分数为 dp[n][m-1].
     
               b. 划分中有一个数为 m. 那就在 n中减去 m , 剩下的就相当
                  于把 n-m 进行划分, 故划分数为 dp[n-m][m];

    
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    long long  a[1005][105],b[1005][105];
    long long inf = 1e18;
    int main()
    {
        int n,m,i,j,k;
        while(~scanf("%d%d",&n,&m)){
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            for(int i = 0 ; i <= m ; i++)
                a[0][i] = 1;
            for(int j = 1; j <= m ; j++){
                for(int i= 1; i <= n; i++){
                    if(i < j){
                        a[i][j] = a[i][j-1];
                        b[i][j] = b[i][j-1];
                      continue;
                    }
                    b[i][j] = b[i][j-1] + b[i-j][j] + (a[i][j-1] + a[i-j][j])/inf;
                    a[i][j] = (a[i][j-1] + a[i-j][j])%inf;
                }
            }
            if(b[n][m])
                printf("%lld",b[n][m]);
            printf("%lld
    ",a[n][m]);
        }
    return 0;
    }
    View Code
    
    
    
     
  • 相关阅读:
    JAVA07-Object类、Date类、Calendar类、System类、包装类、Collection、泛型、List、Set、数据结构、Collections
    大话数据结构03-线性表
    大话数据结构02-算法
    大话数据结构01-数据结构序论
    03-移动营销设计-H5设计方法
    02-移动营销设计-设计流程与规范技巧
    字典的定义和操作 (Python)
    列表的系列操作(python)
    列表操作之定义,切片(取元素)(Python)
    python的基础socket知识
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4466758.html
Copyright © 2020-2023  润新知