zoukankan      html  css  js  c++  java
  • 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
     

     

  • 相关阅读:
    android的进度条使用
    strlen和sizeof的差别
    2012 苏州瑞晟微电子 面试(共两轮,每次近一个半小时)
    最小二乘法多项式曲线拟合原理与实现
    敏捷开发流程总结
    duplicate symbol _*** in:
    C#操作Excel初探
    设计模式(一)工厂模式Factory(创建型)
    Bulk Insert命令具体
    FindWindowEx使用方法
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5430761.html
Copyright © 2011-2022 走看看