Light OJ 1231 1232 1233 Coin Change (DP)

来源:互联网 发布:淘桃美工网 编辑:程序博客网 时间:2024/06/06 12:13

解析:第一个第二个都是简单的背包,不解释。

第三个设dp[i][j]为考虑前i个硬币,凑成j的方案数。

状态转移方程:
dp[i][j] = sigma(dp[i-1][j-k*A[i]]) (0<=k<=C[i])
整理后,得
dp[i][j] = dp[i-1][j]+dp[i][j-A[i]]-dp[i-1][j-(C[i]+1)*A[i]]


[1231's code]:

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;typedef long long LL;const LL MOD = 1e8+7;const int M = 1e6+6;int n,m,a[55],c[55];LL dp[55][1005];int main(){    int i,j,k,cas,T;    scanf("%d",&cas);    for(T = 1;T <= cas;T++){        scanf("%d%d",&n,&m);        for(i = 1;i <= n;i++) scanf("%d",&a[i]);        for(i = 1;i <= n;i++) scanf("%d",&c[i]);        printf("Case %d: ",T);        memset(dp,0,sizeof(dp));        dp[0][0] = 1;        for(i = 1;i <= n;i++){            for(j = 0;j <= m;j++){                for(k = 0;k <= c[i];k++){                    if(j-k*a[i]<0) break;                    dp[i][j] = (dp[i][j]+dp[i-1][j-k*a[i]])%MOD;                }            }        }        printf("%lld\n",dp[n][m]);    }    return 0;}


[1232's code]:

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;typedef long long LL;const LL MOD = 1e8+7;const int M = 1e6+6;int n,m,a[105];LL dp[10005];int main(){    int i,j,k,cas,T;    scanf("%d",&cas);    for(T = 1;T <= cas;T++){        scanf("%d%d",&n,&m);        for(i = 1;i <= n;i++) scanf("%d",&a[i]);        printf("Case %d: ",T);        memset(dp,0,sizeof(dp));        dp[0] = 1;        for(i = 1;i <= n;i++){            for(j = a[i];j <= m;j++){                dp[j] = (dp[j]+dp[j-a[i]])%MOD;            }        }        printf("%lld\n",dp[m]);    }    return 0;}


[1233's code]:

#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>using namespace std;typedef long long LL;const LL MOD = 1e9+7;const int M = 1e6+6;int n,m,a[105],c[105];LL dp[2][100005];int main(){    int i,j,k,cas,T;    scanf("%d",&cas);    for(T = 1;T <= cas;T++){        scanf("%d%d",&n,&m);        for(i = 1;i <= n;i++) scanf("%d",&a[i]);        for(i = 1;i <= n;i++) scanf("%d",&c[i]);        printf("Case %d: ",T);        memset(dp,0,sizeof(dp));        dp[0][0] = 1;        int o,p;        for(i = 1;i <= n;i++){            o = i&1;p = (i+1)&1;            for(j = 0;j <= m;j++){                dp[o][j] = dp[p][j]+(j>=a[i]?dp[o][j-a[i]]:0)                        -(j>=(c[i]+1)*a[i]?dp[p][j-(c[i]+1)*a[i]]:0);                dp[o][j] = (dp[o][j]%MOD+MOD)%MOD;            }        }        int ans = 0;        for(i = 1;i <= m;i++) if(dp[n&1][i]!=0) ans++;        printf("%d\n",ans);    }    return 0;}






0 0
原创粉丝点击