• POJ_3181_Dollar_Dayz_(动态规划,完全部分和,完全背包)


    描述


     
    http://poj.org/problem?id=3181

    FJ有n元钱,有k种商品,各为1,2,...,k-1,k元,问有多少种花掉这n元钱的方法.

    Dollar Dayz
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 5858   Accepted: 2197

    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

    Source

    分析


     

    这是一个完全部分和问题.对于多重部分和问题,可以用多重背包,但是由于有三层循环,会超时(即便使用二进制优化),所以有特殊的算法.而完全部分和问题可以直接用完全背包做.

    注意:

    1.是大数,要用高精度,或者两位分别存高低位:

    unsigned long long 上限是1.8e19,所以每一位存1e17.

    2.注意如果高位有数,低位要保证有前导0.

     1 #include <cstdio>
     2 #include <algorithm>
     3 #define ull unsigned long long
     4 const int maxw=1005,maxn=105;
     5 const ull mod=100000000000000000;
     6 int W,N;
     7 ull dp[maxw][2];
     8 
     9 void solve()
    10 {
    11     dp[0][0]=1;
    12     for(int i=1;i<=N;i++)
    13     {
    14         for(int j=i;j<=W;j++)
    15         {
    16             dp[j][0]+=dp[j-i][0];
    17             dp[j][1]+=dp[j-i][1];
    18             dp[j][1]+=dp[j][0]/mod;
    19             dp[j][0]%=mod;
    20         }
    21     }
    22     if(dp[W][1])
    23     {
    24         printf("%llu",dp[W][1]);
    25         printf("%017llu
    ",dp[W][0]);
    26     }
    27     else
    28     {
    29         printf("%llu
    ",dp[W][0]);
    30     }
    31 }
    32 
    33 int main()
    34 {
    35 #ifndef ONLINE_JUDGE
    36     freopen("john.in","r",stdin);
    37     freopen("john.out","w",stdout);
    38 #endif
    39     scanf("%d%d",&W,&N);
    40     solve();
    41 #ifndef ONLINE_JUDGE
    42     fclose(stdin);
    43     fclose(stdout);
    44     system("john.out");
    45 #endif
    46     return 0;
    47 }
    View Code
     

     

  • 相关阅读:
    实验一框架选择及其分析
    站立会议(一)
    关于有多少个1的计算
    寻找水王问题
    如何买到更便宜的书
    NABCD
    二维数组首尾相连求最大子矩阵
    环数组求最大子数组的和
    二维数组求最大矩阵
    关于铁道大学基础教学楼电梯调查
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5430761.html
Copyright © 2020-2023  润新知