zoukankan      html  css  js  c++  java
  • poj 1742 Coins

    题目大意:某人有各种面值为ai的硬币ci个,问他能凑够1到m价格中的几个?

    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
    
    动态规划,
    dp[i][j]表示用前 i 个物品凑成 j 时物品还剩多少个,如果凑不出,就为-1
    代码如下
     1 /*
     2 if(dp[i-1][j] >= 0) {
     3     dp[i][j] = c[i];
     4 }
     5 else {
     6     if(j < v[i] || dp[i][j-v[i]] < 0) {
     7         dp[i][j] = -1;
     8     }
     9     else {
    10         dp[i][j] = dp[i][j-v[i]] - 1;
    11     }
    12 }*/
    13 #include <cstdio>
    14 #include <cstring>
    15 #include <cstdlib>
    16 
    17 int dp[102][100002];
    18 int a[102], c[102];
    19 int main(int argc, char const *argv[])
    20 {
    21     int n, m;
    22     freopen("input.txt","r",stdin);
    23     while(scanf("%d %d",&n,&m) != EOF && (n != 0 && m != 0)) {
    24         for(int i = 1; i <= n; i++) {
    25             scanf("%d",&a[i]);
    26         }
    27         for(int i = 1; i <= n; i++) {
    28             scanf("%d",&c[i]);
    29         }
    30         memset(dp, 0, sizeof(dp));
    31         for(int i = 1; i <= n; i++) {
    32             dp[i][0] = c[i];
    33         }
    34         for(int i = 0; i <= m; i++) {
    35             dp[0][i] = -1;
    36         }
    37         for(int i = 1; i <= n; i++) {
    38             for(int j = 1; j <= m; j++) {
    39                 if(dp[i-1][j] >= 0) {
    40                     dp[i][j] = c[i];
    41                 }
    42                 else {
    43                     if(j < a[i] || dp[i][j-a[i]] < 0)  {
    44                         dp[i][j] = -1;
    45                     }
    46                     else {
    47                         dp[i][j] = dp[i][j-a[i]] - 1;
    48                     }
    49                 }
    50             }
    51         }
    52         int ans = 0;
    53         for(int i = 1; i <= m; i++) {
    54             if(dp[n][i] >= 0) {
    55                 ans++;
    56             }
    57         }
    58         printf("%d
    ",ans);
    59     }
    60     return 0;
    61 }

    关于转移方程,如果dp[i-1][j] >= 0 即用前i-1个物品就可以实现j,那么dp[i][j]就是第i个物品的个数

    如果dp[i-1][j] == -1

    如果j比第i个物品的价值小,那么凑不出

    如果用前i个物品凑不出j-v[i],那么也同样凑不出j

    否则,dp[i][j]就为凑过j-1的物品数再减1

    再将dp化为一维数组

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 
     5 int dp[100002];
     6 int a[102], c[102];
     7 int main(int argc, char const *argv[])
     8 {
     9     int n, m;
    10     //freopen("input.txt","r",stdin);
    11     while(scanf("%d %d",&n,&m) != EOF && (n != 0 && m != 0)) {
    12         for(int i = 1; i <= n; i++) {
    13             scanf("%d",&a[i]);
    14         }
    15         for(int i = 1; i <= n; i++) {
    16             scanf("%d",&c[i]);
    17         }
    18         memset(dp, 0, sizeof(dp));
    19         for(int i = 1; i <= m; i++) {
    20             dp[i] = -1;
    21         }
    22         for(int i = 1; i <= n; i++) {
    23             for(int j = 0; j <= m; j++) {
    24                 if(dp[j] >= 0) {
    25                     dp[j] = c[i];
    26                 }
    27                 else if( j < a[i] || dp[j-a[i]] < 0) {
    28                     dp[j] = -1;
    29                 }
    30                 else {
    31                     dp[j] = dp[j-a[i]] - 1;
    32                 }
    33             }
    34         }
    35         int ans = 0;
    36         for(int i = 1; i <= m; i++) {
    37             if(dp[i] >= 0) {
    38                 ans++;
    39             }
    40         }
    41         printf("%d
    ",ans);
    42     }
    43     return 0;
    44 }

    貌似用母函数也可以求解这道题

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <cstring>
     4 #include <iostream>
     5 using namespace std;
     6 
     7 int a[102], c[102];
     8 int c1[100002] = {0};
     9 int c2[100002] = {0};
    10 int ans[100002] = {0};
    11 int p;
    12 int n, m;
    13 
    14 void multi(int cn1, int cn2) {
    15     cn1 = min(cn1, m);
    16     cn2 = min(cn2, m);
    17     for(int i = 0; i <= cn1; i++) {
    18         for(int j = 0; j <= cn2; j++) {
    19             ans[i+j] = ans[i+j] + c1[i]*c2[j];
    20         }
    21     }
    22     p = cn1 + cn2;
    23 }
    24 
    25 int main(int argc, char const *argv[])
    26 {
    27     
    28     freopen("input.txt","r",stdin);
    29     while(scanf("%d %d",&n,&m) != EOF && (n != 0 && m != 0)) {
    30         for(int i = 1; i <= n; i++) {
    31             scanf("%d",&a[i]);
    32         }
    33         for(int i = 1; i <= n; i++) {
    34             scanf("%d",&c[i]);
    35         }
    36         memset(ans, 0, sizeof(ans));
    37         for(int i = 0; i <= c[1]; i++) {
    38             ans[i*a[1]] = 1;
    39         }
    40         p = a[1]*c[1];
    41         for(int i = 2; i <= n; i++) {
    42             memset(c1, 0, sizeof(c1));
    43             memset(c2, 0, sizeof(c2));
    44             for(int j = 0; j <= p; j++) {
    45                 c1[j] = ans[j];
    46             }
    47             for(int j = 0; j <= c[i]; j++) {
    48                 c2[j*a[i]] = 1;
    49             }
    50             memset(ans, 0, sizeof(ans));
    51             multi(p,a[i]*c[i]);
    52         }
    53         int anss = 0;
    54         for(int i = 1; i <= m; i++) {
    55             if(ans[i] > 0) {
    56                 anss++;
    57             }
    58         }
    59         printf("%d
    ",anss);
    60     }
    61     return 0;
    62 }

    但是超时了

  • 相关阅读:
    手机号不能为空
    选项卡套选项卡
    可以在一个html的文件当中读取另一个html文件的内容
    价格计算
    v形 加强版
    V形
    生成100个Div
    伪元素::after和::before
    数组中的toString,toLocalString,valueOf方法有什么区别
    JavaScript toLocaleString() 方法
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5830752.html
Copyright © 2011-2022 走看看