HDU2844:Coins

来源:互联网 发布:java开源博客系统源码 编辑:程序博客网 时间:2024/05/21 14:50

题意:有n个不同价值的硬币,每种有Mi个,问能组成多少个小于等于m的不同数字。
思路:典型多重部分和问题,时间复杂度O(n*W),给你n个不同大小的数,每种各Mi个,判断这些数字之间选出若干使它们的和存在之类的….
搜题解发现很多人用多重背包,又写一遍,当做复习。

#include <fstream>#include <iostream>#include <string>#include <complex>#include <math.h>#include <set>#include <vector>#include <map>#include <queue>#include <stdio.h>#include <stack>#include <algorithm>#include <list>#include <ctime>#include <memory.h>#include <ctime>#include <assert.h>#define rep(i,a,n) for (int i=a;i<n;i++)#define per(i,a,n) for (int i=n-1;i>=a;i--)#define pb push_back#define mp make_pair#define all(x) (x).begin(),(x).end()#define fi first#define se second#define eps 1e-8#define M_PI 3.141592653589793typedef long long ll;const ll mod=1000000007;const int inf=99999999;ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}using namespace std;int dp[110000],v[110],c[110];int main(){    int n,m;    while(~scanf("%d %d",&n,&m)&&(n+m)){        for(int i=0;i<=m;i++) dp[i]=-1;        dp[0]=1;        for(int i=0;i<n;i++) scanf("%d",&v[i]);        for(int i=0;i<n;i++) scanf("%d",&c[i]);        for(int i=0;i<n;i++){            for(int j=0;j<=m;j++){                if(dp[j]>=0) dp[j]=c[i];                else if(dp[j-v[i]]<=0||j<v[i]) dp[j]=-1;                else dp[j]=dp[j-v[i]]-1;            }        }        int res=0;        for(int i=1;i<=m;i++){           if(dp[i]>=0) res++;        }        printf("%d\n",res);    }}
#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;const int MAX=100000;int dp[MAX];int c[MAX],w[MAX];int v;void ZeroOnePack(int cost,int wei){    int i;    for(i = v;i>=cost;i--)    {        dp[i] = max(dp[i],dp[i-cost]+wei);    }}void CompletePack(int cost,int wei){    int i;    for(i = cost;i<=v;i++)    {        dp[i] = max(dp[i],dp[i-cost]+wei);    }}void MultiplePack(int cost,int wei,int cnt){    if(v<=cnt*cost)    {        CompletePack(cost,wei);        return ;    }    else    {        int k = 1;        while(k<=cnt)        {            ZeroOnePack(k*cost,k*wei);            cnt = cnt-k;            k = 2*k;        }        ZeroOnePack(cnt*cost,cnt*wei);    }}int main(){    int n;    while(~scanf("%d%d",&n,&v),n+v)    {        int i;        for(i = 0;i<n;i++)        scanf("%d",&c[i]);        for(i = 0;i<n;i++)        scanf("%d",&w[i]);        memset(dp,0,sizeof(dp));        for(i = 0;i<n;i++)        {            MultiplePack(c[i],c[i],w[i]);        }        int sum = 0;        for(i = 1;i<=v;i++)        {            if(dp[i]==i)            {                sum++;            }        }        printf("%d\n",sum);    }    return 0;}
0 0
原创粉丝点击