码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 1742(Coins)

时间:2020-04-05 13:58:49      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:style   print   src   背包问题   ring   情况   技术   lap   display   

题目链接: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\n",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

 

POJ 1742(Coins)

标签:style   print   src   背包问题   ring   情况   技术   lap   display   

原文地址:https://www.cnblogs.com/jaszzz/p/12636750.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!