您的位置:首页 > 其它

ahu-730-幸运抽奖

2016-04-09 15:55 281 查看
最多情况不超过long long,先DP打表再取模。

dp[52][1300][52] 一维代表此时选择的数的个数,二维代表此时的总和,三维代表此时选的最大数。

dp[i][j][k] = dp[i-1][j-1][1]+dp[i-1][j-2][2]+…dp[i-1][j-k1+1][k1];

有很多情况不用递推可以剪掉。

思路太繁琐,有没有人用二维DP或组合数学AC的啊!!!

#include<cstdio>
#include<cstring>
#include<algorithm>
long long dp[52][1300][52] = {0},n,m,la,mi,mod,am[2500],ans;
int main()
{
dp[0][0][0] = 1;
for(int i=1;i<=50;i++)
for(int j=(i+1)*i/2;j<=(50+50-i+1)*i/2;j++)
for(int k=i;k<=j&&k<=50;k++)
{
dp[i][j][k] = 0;
for(int k1=0;k1<k;k1++)
dp[i][j][k] += dp[i-1][j-k][k1];
}
while(scanf("%I64d%I64d%I64d",&n,&m,&mod)!=EOF)
{
memset(am,0,sizeof(am));
la = (n+n-m+1)*m/2;
mi = (1+m)*m/2;
for(int i=mi;i<=la;i++)
for(int j=1;j<=n;j++)
{
am[i]+=dp[m][i][j];
am[i]%=mod;
}
ans = 0;
for(int i=mi;i<=la;i++)
for(int j=mi;j<i;j++)
ans = (ans+(am[i]%mod)*(am[j]%mod)%mod)%mod;
printf("%I64d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: