码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-04-29 19:41:54      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:

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\n",a[n][m]);
    }
return 0;
}
View Code

 

 

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

标签:

原文地址:http://www.cnblogs.com/zero-begin/p/4466758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!