HDU5519-数位DP或者FFT
来源:互联网 发布:天行健网络 编辑:程序博客网 时间:2024/06/05 19:23
https://vjudge.net/contest/166969#problem/K
FFT 本渣渣是真不会。但是目标是要学会它。不要求具体会,会用板子就行。
用的数位Dp。
给定 0 1 2 3 4 这5个数,以及他们能出现的个数,问你用这些数最多能够成多少个不含前导0的n位数。
#include <iostream>#include <cstdio>#include <cstring>#define mod 1000000007#define MAXN 15005#define LL long long intusing namespace std;const int END=1<<5;int n, dp[MAXN][END+5], a[10];LL fac[MAXN], ni[MAXN], cnt[END+5];LL quickpow(LL m,LL n){ int b=1; while(n>0) { if(n&1)b=(b*m)%mod; n=n>>1; m=(m*m)%mod; }return b;}int get(LL n){ int ans=0; while(n>0) { if(n&1) ans++; n>>=1; } return ans;}void init(){ fac[0]=fac[1]=ni[0]=ni[1]=1; for(int i=2;i<=15000;++i) { fac[i]=fac[i-1]*i%mod; ni[i]=quickpow(fac[i],1000000005); } //cnt[i]表示i中有几个1 for(int i=1;i<END;++i)cnt[i]=get(i);}LL c(int n,int m){return fac[n]*ni[m]%mod*ni[n-m]%mod;}int solve(){ memset(dp,0,sizeof dp); for(int s=0;s<END;++s) if(cnt[s^(END-1)]&1)dp[0][s]=-1; else dp[0][s]=1; for(int i=1;i<=n;++i) { for(int s=0;s<END;++s) { dp[i][s]=dp[i][s]+dp[i-1][s]*cnt[s]; for(int k=0;k<5;++k) if(!((s>>k)&1)&&a[k]<i) dp[i][s|(1<<k)]=dp[i][s|(1<<k)]+dp[i-1-a[k]][s]*c(i-1,a[k]); } } return dp[n][END-1];}int work(){ int ans=solve(); if(a[0]>0) { --n, --a[0]; ans=ans-solve(); } return ans;}int main(){ init(); int t, cas=0; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0;i<5;++i)scanf("%d",&a[i]); printf("Case #%d: %d\n",++cas,work()); } return 0;}
阅读全文
0 0
- HDU5519-数位DP或者FFT
- 【数位DP】CF55D BZOJ3329 HDU4352 SGU390 HDU5519
- 204A (数学题或者数位DP?)
- 数位dp
- 数位DP
- 数位DP
- 数位dp
- 数位dp
- 数位dp
- 数位DP
- 数位dp
- 数位DP
- 【数位DP】
- 数位DP
- 数位dp
- 数位dp
- 数位DP
- 数位DP
- AOJ 0118 Property Distribution 【DFS】
- shoutcast 数据获取
- 原生JS实现简单抽人名功能实例
- setInterval,setTimeout
- OSI分层,TCP/IP分层
- HDU5519-数位DP或者FFT
- 徇私舞弊不移交刑事案件罪
- yum制作(笔记)
- MySQL表的约束
- Eureka Server的高可用
- Android—Activity启动
- 自己动手写操作系统(二)
- 错误中学习--Exception occurred during processing request: null
- 线程