Dollar Dayz (大数dp fuck!不是多组数据!!)

Dollar Dayz

Time Limit: 1000ms
Memory Limit: 65536KB
64-bit integer IO format: %lld      Java class name: Main

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

Source

USACO 2006 January Silver
思路:一个老生长谈的整数划分问题
注意:是大数 long long 但是!!是一组一组的数据 不是多组!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include<bits/stdc++.h>
using namespace std;
const long long inf=1e15;
long long num[100];
long long dp[1010][110][10];

void add(int a,int b,int c,int d)  //每位存15位数
{
    long long mx=0;
    for(int i=0; i<3; i++)
    {
        long long z=dp[a][b][i]+dp[c][d][i]+mx;
        dp[a][b][i]=z%inf;
        mx=z/inf;
    }
}

void print(int a,int b)//
{
    int t=0;
    for(int i=0; i<3; i++)
    {
        num[i]=dp[a][b][i];
        //printf("%d %d %d %d\n",a,b,i,dp[a][b][i]);
        if(dp[a][b][i]!=0)
            t=i;
    }
    for(int i=t; i>=0; i--)
    {
        if(i!=t)
            printf("%015lld",num[i]);
        else
            printf("%lld",num[i]);
    }
    printf("\n");
}

int main()
{


    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        memset(dp,0,sizeof(dp));
        //printf("*****\n");
        for(int i=1; i<=n+1; i++)
        {
            dp[i][1][0]=1;
            int aaa=min(i,k);
            for(int j=2; j<=aaa; j++)
            {
                for(int k=1; k<=j; k++)
                {
                    if(i-k<k)
                        add(i,j,i-k,i-k);    //dp[i][j] = dp[i][j] + dp[i-k][i-k];
                    else
                        add(i,j,i-k,k);      // dp[i][j] = dp[i][j] + dp[i-k][k];
                }
            }

        }

        int t=0;
        for(int i=0; i<3; i++)
        {
            num[i]=dp[n+1][k][i];
            //printf("%d %d %d %d\n",a,b,i,dp[a][b][i]);
            if(dp[n+1][k][i]!=0)
                t=i;
        }
        for(int i=t; i>=0; i--)
        {
            if(i!=t)
                printf("%015lld",num[i]);//补零
            else
                printf("%lld",num[i]);
        }
        printf("\n");
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值