• POJ 1742 Coins 【可行性背包】【非原创】


    People in Silverland use coins.They have coins of value A1,A2,A3...An Silverland dollar.One day Tony opened his money-box and found there were some coins.He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch. 
    You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins. 

    Input

    The input contains several test cases. The first line of each test case contains two integers n(1<=n<=100),m(m<=100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1<=Ai<=100000,1<=Ci<=1000). The last test case is followed by two zeros.

    Output

    For each test case output the answer on a single line.

    Sample Input

    3 10
    1 2 4 2 1 1
    2 5
    1 4 2 1
    0 0
    

    Sample Output

    8
    4

    题意:给你n种面值的硬币,面值为a1...an,数量分别为c1...cn,求问,在这些硬币的组合下,能够多少种面值,该面值不超过m

    思路:设d[i][j]——前i种硬币,凑成总值j时,第i种硬币所剩余的个数。(能否想到这样构造是个难点

       默认d[i][j] = -1,代表无法凑成总值j

       转移方程为,若d[i-1][j]≥0,代表前i-1种已能够凑成j,那么就不必花费第i种硬币,所以d[i][j] = c[i]

       否则就看d[i][j-a[i]]的值,显然如果j < a[i],那么d[i][j] = -1,否则d[i][j-a[i]] ≤ 0,代表此刻第i种硬币已使用完了,所以自然d[i][j] = -1;

       否则,d[i][j] = d[i][j-a[i]]-1;

       可以看到d[i][]的值只与d[i-1][]和d[i][]有关,所以我们可以采用一维数组的形式,从而能够节省内存空间。

     AC代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 typedef unsigned long long ll;
     6 const int maxn = 1e3 + 10;
     7 const int inf = 0x3f3f3f3f;
     8 const int maxx = 1e5 + 10;
     9 int dp[maxx];
    10 int a[maxn];
    11 int c[maxn];
    12 bool vis[maxx];
    13 int main()
    14 {
    15     int n, m;
    16     while(~scanf("%d %d", &n, &m),(n||m))
    17     {
    18 
    19         memset(dp, -1, sizeof(dp));
    20         for(int i = 1; i <= n; ++i)
    21         {
    22             scanf("%d", a+i);
    23        //     printf("%d ", a[i]);
    24         }
    25         for(int i = 1; i <= n; ++i)
    26         {
    27             scanf("%d", c+i);
    28         }
    29         dp[0] = 0;
    30         for(int i = 1; i <= n; ++i)
    31         {
    32             for(int j = 0; j <= m; ++j)
    33             {
    34                 if(dp[j] >= 0)
    35                 {
    36                     dp[j] = c[i];
    37                 }
    38 
    39                 else if(j - a[i] >= 0 && dp[j - a[i]] > 0)
    40                 {
    41                     dp[j] = dp[j - a[i]] - 1;
    42                 }
    43             }
    44         }
    45         int ans = 0;
    46         for(int i = 1; i <= m; ++i)
    47         {
    48          //   printf("%d ", dp[i]);
    49             if(dp[i] >= 0) ++ans;
    50         }
    51         printf("%d
    ",ans);
    52     }
    53     return 0;
    54 }
    View Code

    转载博客:戳这里

  • 相关阅读:
    《陶哲轩实分析》习题10.4.3
    陶哲轩实分析定理10.1.3:导数运算的积法则和商法则
    《数学分析新讲》_张筑生,12.5节:隐函数定理(1)
    《数学分析新讲》_张筑生,12.5节:隐函数定理(1)
    《陶哲轩实分析》定理10.1.15:导数的链法则
    我的博客园的CSS和html设置
    陶哲轩实分析定理10.1.3:导数运算的积法则和商法则
    关于Eclipse中一个错误排查总结
    RMI, Dynamic Proxies, and the Evolution of Deployment
    Java垃圾回收机制浅析
  • 原文地址:https://www.cnblogs.com/zmin/p/9329328.html
Copyright © 2020-2023  润新知