zoukankan      html  css  js  c++  java
  • POJ 1742(Coins)

    题目链接:http://poj.org/problem?id=1742

    与一般的背包问题不一样,这是要计算满足条件的情况的数量,而不是计算最值,一开始的思路就是按照书上的类比:

    dp[i][j] := 用前i种硬币能否凑成j

    递推:dp[i][j] = (dp[i – 1][j – k * A[i]])为真的时候

    但是 MLE,其实一点都不惊讶吧,数组开那么大肯定会出问题呀,所以只能放弃二维数组:

    dp[j] := 在第i次循环时之前表示用前 i-1 种硬币凑成 j 时第 i 种硬币最多能剩余多少个(-1表示配不出来),循环之后就表示第i次的状态

    ac代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #define MAX_N 101
     6 using namespace std;
     7 int n,m;
     8 int a[MAX_N],c[MAX_N];
     9 int dp[100005];
    10 
    11 void solve(){
    12     memset(dp,-1,sizeof(dp));
    13     dp[0]=0;
    14     for(int i=0;i<n;i++){
    15         for(int j=0;j<=m;j++){
    16             if(dp[j]>=0)
    17                 dp[j]=c[i];
    18             else if(j<a[i]||dp[j-a[i]]<=0)
    19                 dp[j]=-1;
    20             else
    21                 dp[j]=dp[j-a[i]]-1;
    22         }
    23     }
    24     int ans=0;
    25     for(int i=1;i<=m;i++)
    26         if(dp[i]>=0)    ans++;
    27     printf("%d
    ",ans);
    28 }
    29 
    30 int main(void){
    31     while(scanf("%d%d",&n,&m)&&(n||m)){
    32         for(int i=0;i<n;i++)    scanf("%d",&a[i]);
    33         for(int j=0;j<n;j++)    scanf("%d",&c[j]);
    34         solve();
    35     }
    36 
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    vue-修改vue项目运行端口号
    任正非521央视采访全文
    是施压还是真的决裂?
    贸易战风波继续
    华为对封杀的态度和格局
    美国封锁对华为的影响
    布鲁克斯法则 (Brooks's Law)
    2019第20周日
    如何让自己走的更远
    如何应对中年危机
  • 原文地址:https://www.cnblogs.com/jaszzz/p/12636750.html
Copyright © 2011-2022 走看看