POJ 3046
Posted wpbing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3046相关的知识,希望对你有一定的参考价值。
题目大意:蚂蚁牙黑,蚂蚁牙红:有A只蚂蚁,来自T个家族,分别记为ant[i]个。同一个家族的蚂蚁长得一样,但是不同家族的蚂蚁牙齿颜色不同。任取n只蚂蚁(S <= n <= B),求能组成几种集合?
状态:dp[i][j]:前i种中选j个可以组成的种数
决策:第i种选k个,k<=ant[i] && j-k>=0
转移:dp[i][j]=Σdp[i-1][j-k]
#include<stdio.h> #include<string.h> int dp[1005][10050]; int num[10050]; int main(){ int n,m,a,b,x; while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF){ memset(num,0,sizeof(num)); for(int i=0;i<m;i++){ scanf("%d",&x); num[x]++; } memset(dp,0,sizeof(dp)); for(int i=0;i<=num[1];i++) dp[1][i]=1; for(int i=2;i<=n;i++){ for(int j=0;j<=b;j++){ for(int k=0;k<=num[i];k++){ if(j>=k) { dp[i][j]+=dp[i-1][j-k]; dp[i][j]%=1000000; } } } } int ans=0; for(int i=a;i<=b;i++){ ans+=dp[n][i]; ans%=1000000; } printf("%d ",ans); } return 0; }
还有一种
dp[i][j] = dp[i-1][j] + dp[i][j-1] - dp[i-1][j-ant[i]-1]
#include<iostream> using namespace std; #define MOD 1000000 int T, A, S, B; int ant[1005]; int dp[2][100000]; int ans; int main() { scanf("%d%d%d%d", &T, &A, &S, &B); for (int i = 1; i <= A; i++) { int aa; scanf("%d", &aa); ant[aa]++; } dp[0][0] = dp[1][0] = 1; for (int i = 1; i <= T; i++) for (int j = 1; j <= B; j++) if (j - ant[i] - 1 >= 0) dp[i % 2][j] = (dp[(i - 1) % 2][j] + dp[i % 2][j - 1] - dp[(i - 1) % 2][j - ant[i] - 1] + MOD) % MOD; //在取模时若出现了减法运算则需要先+Mod再对Mod取模,防止出现负数(如5%4-3%4为负数) else dp[i % 2][j] = (dp[(i - 1) % 2][j] + dp[i % 2][j - 1]) % MOD; for (int i = S; i <= B; i++) ans = (ans + dp[T % 2][i]) % MOD; printf("%d ", ans); return 0; }
以上是关于POJ 3046的主要内容,如果未能解决你的问题,请参考以下文章