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\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 }

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

时间: 2024-10-13 22:21:49

POJ 1742(Coins)的相关文章

POJ 2253-Frogger (Prim)

题目链接:Frogger 题意:两只青蛙,A和B,A想到B哪里去,但是A得弹跳有限制,所以不能直接到B,但是有其他的石头作为过渡点,可以通过他们到达B,问A到B的所有路径中,它弹跳最大的跨度的最小值 PS:最小生成树过的,刚开始用Dijstra做,Kao,精度损失的厉害,对于Dijksra的变形不大会变啊,看了Discuss有人用最小生成树过,我一划拉,还真是,敲了,就过了,等会研究研究最短路的各种变形,有模板不会变,不会灵活应用,渣渣就是渣渣. ME               Time 10

poj 1861(最小生成树)

Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the company, they can be connected to each other using cables. Since each worker of the company must have access

POJ 2352 (stars)

[题意描述] 就是给定n个星星的x,y坐标,y坐标按照从小到大的顺序进行排列,x坐标随机排列.下面求对于每个星星而言,其它星星的x,y的坐标都小于等于该星星的数目,然后输出所有的情况. [思路分析] 我们这道题可以采用树状数组求解,将x+1作为树状数组的底标. [AC代码] #include<iostream> #include<bitset> #include<cstdio> #include<cstring> #include<algorithm&

poj Sudoku(数独) DFS

Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 13665   Accepted: 6767   Special Judge Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure.

POJ 3419 (rmq)

这道题是rmq,再加上一个解决溢出. 刚开始我也想过用rmq,虽然不知道它叫什么,但是我知道应该这样做.可是后来没想到这道题的特殊性,也就是解决溢出的方法,就放弃了. rmq可以用线段树,也可以用dp.  这道题都可以过的,而且线段树要快一些. #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; #define m

Coins POJ - 1742 (背包判断可行性)

 题目链接:  POJ - 1742 题目大意: n个货币,每个货币有一定的数量,然后问你从1~m有多少个数能被凑出来? 具体思路: dp[i][j]代表前i个凑出j元钱第i个的最大剩余量. 二维(超内存): 1 #include<iostream> 2 #include<cstring> 3 #include<stdio.h> 4 using namespace std; 5 # define ll long long 6 # define lson l,mid,rt

POJ题目(转)

http://www.cnblogs.com/kuangbin/archive/2011/07/29/2120667.html 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:     (

poj数论(转)

1.burnside定理,polya计数法    这个大家可以看brudildi的<组合数学>,那本书的这一章写的很详细也很容易理解.最好能完全看懂了,理解了再去做题,不要只记个公式.    *简单题:(直接用套公式就可以了)    pku2409 Let it Bead       pku2154 Color    pku1286 Necklace of Beads    *强烈推荐:(这题很不错哦,很巧妙)    pku2888 Magic Bracelet2.置换,置换的运算 置换的概念

poj 1200 (hash)

Crazy Search Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23168   Accepted: 6513 Description Many people like to solve hard puzzles some of which may lead them to madness. One such puzzle could be finding a hidden prime number in a gi