BZOJ3612 [Heoi2014]平衡

来源:互联网 发布:外阴白斑知乎 编辑:程序博客网 时间:2024/06/10 21:21

想了好长时间的题,然后发现ahcisy A了,最后还是看了题解

首先我们需要掌握一些基础物理知识……虽然大家可能没上过高中课但是初中课还是上过一点的把……

我们需要计算1~n里选j个数,和为i的方案数

而事实上就是把i拆分成1~n里互不相同的j个数的方案数

几位f[i][j]

考虑最小值是否为1,若为1,f[i-j][j-1],若不为1,f[i-j][j]

再减去最大值大于n的方案,即减去f[i-n-1][j-1]

然后就可以算了

#include<iostream>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<cstdlib>#include<cstdio>#include<map>#include<bitset>#include<set>#include<stack>#include<vector>#include<queue>using namespace std;#define MAXN 1000010#define MAXM 11#define ll long long#define eps 1e-8#define MOD 1000000007#define INF 1000000000int n,k,p;int f[MAXN][MAXM];int main(){int i,j;int tmp;scanf("%d",&tmp);while(tmp--){scanf("%d%d%d",&n,&k,&p);int N=n*10;f[0][0]=1;for(i=1;i<=N;i++){for(j=1;j<=k&&j<=i;j++){f[i][j]=(f[i-j][j-1]+f[i-j][j])%p;if(i>n){(f[i][j]+=p-f[i-n-1][j-1])%=p;}}}int ans=0;for(i=0;i<=N;i++){for(j=0;j<=k;j++){(ans+=f[i][j]*f[i][k-j]%p)%=p;if(j){(ans+=f[i][j-1]*f[i][k-j]%p)%=p;}}}printf("%d\n",ans);}return 0;}/*106 5 100004 1 100009 6 100004 6 100005 1 100008318 10 99739862 9 99738234 9 99739424 9 99739324 9 9973*/


0 0