当前位置: 代码迷 >> 综合 >> POJ - 1742 Coins(DP+贪心)
  详细解决方案

POJ - 1742 Coins(DP+贪心)

热度:21   发布时间:2023-11-25 08:26:43.0

HDU - 2844 Coins

POJ - 1742 Coins

给定 N 种硬币,其中第 i 种硬币的面值为 Ai,共有 Ci 个。

从中选出若干个硬币,把面值相加,若结果为 S,则称“面值 S 能被拼成”。

求 1?M 之间能被拼成的面值有多少个。

输入格式
输入包含多组测试用例。

每组测试用例第一行包含两个整数 N 和 M。

第二行包含 2N 个整数,分别表示 A1,A2,…,AN 和 C1,C2,…,CN。

当输入用例 N=0,M=0 时,表示输入终止,且该用例无需处理。

输出格式
每组用例输出一个结果,每个结果占一行。

数据范围
1≤N≤100,
1≤M≤10^5,
1≤Ai≤10^5,
1≤Ci≤1000

Sample Input

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

Sample Output

8
4

算法(贪心+动态规划)

时间复杂度O(NM)

#include<cstdio>
#include<cstring>
using namespace std;
const int N = 110, M = 100010;
int n,m;
int f[M],g[M];
int v[N],s[N];
int main()
{
    while(scanf("%d%d",&n,&m)&&n+m){
    for(int i=1;i<=n;i++) scanf("%d",&v[i]);for(int i=1;i<=n;i++) scanf("%d",&s[i]);memset(f,0,sizeof f);f[0]=1;for(int i=1;i<=n;i++){
    memset(g,0,sizeof g);for(int j=v[i];j<=m;j++)if(!f[j]&&f[j-v[i]]&&g[j-v[i]]<s[i]){
    g[j]=g[j-v[i]]+1;f[j]=1;}}int res=0;for(int i=1;i<=m;i++) res+=f[i];printf("%d\n",res);}return 0;
}