HZOJ 20190719 That day we promised convention (dp + number of combinations)

The subject background really reminds me of that year. . .

Do not say, get on this question, a glance or a good 30 minutes to get violent, but because of a mentality problem when I did not deal with the details of the exam burst zero.

The complexity of the general idea of ​​30 minutes of violence should be $ O (nmd) $, but the range of data d really horrible, simply can not AC.

30 ideas seem optimization space is not great (but God Ben came up with rapid power to accelerate the transfer matrix, TQL).

We consider change my thinking, first of all d certainly can not be put in the complexity, but also how that shift it, because we observed a maximum of n biscuits, so the real number of days up to give her a biscuit that is n days, then we according to this design status: set $ f [i] [j] $ denotes the total number of actually her days $ I $, $ J $ give the biscuits. Then we can transition to a state equation that is $ f [i] [j] = \ Sigma_ {k = jm} ^ j-1 {f [i-1] [k]} $,

$ Ans = \ Sigma {f [i] [n] * C_d ^ i} $. Or a good understanding of the lie, but the complexity of our current dp formula is still $ (n ^ 3) $ of O, consider optimizing behind the formula is a range and form, so it is easy to think of prefixes and optimization. Complexity becomes $ O (n ^ 2) $.

There is this question points to note: First, d is too large to find a way that we usually use, it is best to combine several points made about solving equations.

             Followed by the second layer loop, it should have been enumerated J $ $ $ $ i from the $ i * (m-1) $, but the prefix and n-$ $ to be processed, and because you are prefix To the next layer services, but the next level is likely to use $ n $, so prefix and must be tackled to $ n $.

Before optimizing dp title still much to do, this problem can be considered and thought of it.

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #include<vector>
 7 #define int long long
 8 #define ll long long
 9 using namespace std;
10 const int N=2005;
11 const int mod=998244353;
12 int dp[N][N],sum[N][N],inv[N];
13 int qpow(int a,int b){
14     int ans=1;
15     a%=mod;
16     while(b){
17         if(b&1) ans=ans*a%mod;
18         b>>=1;
19         a=a*a%mod;
20     }
21     return ans; 
22 }
23 /*inline int C(int a,int b){
24     int js=1ll,facd=1ll;
25     for(register int i=1;i<=b;i++) js=(js*i)%mod;
26     for(register int i=a-b+1;i<=a;i++) {facd=i%mod*facd%mod;cout<<"L"<<facd<<endl;}
27     return facd*qpow(js,mod-2)%mod; 
28 }*/
29 /*inline int C(int x,int y){
30      int facd=1ll,faci=1ll;
31      x%=mod;
32      for(register int i=2;i<=x;++i)     faci=(faci*i)%mod;
33      for(register int i=y-x+1;i<=y;++i) facd=i%mod*facd%mod;
34      int inv=qpow(faci,mod-2);
35      //printf("%lld %lld %lld\n",faci,facd,inv);
36      return facd*inv%mod;
37 }*/
38 int C(int y,int x){
39     if(y<0ll||x<0ll||y<x)return 0;
40     y%=mod;
41     if(y==0ll||x==0ll)return 1;
42     ll ans=1;
43     for(int i=0ll;i<x;i++)
44         ans=ans*(y-i)%mod;
45     for(int i=1ll;i<=x;i++)
46         ans=ans*inv[i]%mod;
47     return ans;
48 }
49 signed main(){
50     int n,m,d;
51     for(int i=1ll;i<=2000ll;i++)
52         inv[i]=qpow(i,mod-2ll);
53     while(~scanf("%lld%lld%lld",&n,&d,&m)){
54         if(!n&&!m&&!d) break;
55         if(n>d*(m-1)) {puts("0");continue;}
56         memset(dp,0,sizeof(dp));
57         memset(sum,0,sizeof(sum));
58         for(int i=1;i<m;i++){
59             dp[1][i]=1;
60             sum[1][i]=dp[1][i]+sum[1][i-1];
61         }
62         for(int i=m;i<=n;i++) sum[1][i]=sum[1][i-1];
63         int ans=0;
64         ans+=(dp[1][n]*C(d,1ll))%mod;
65         for(int i=2;i<=min(d,n);i++){
66             for(int j=i;j<=n;j++){
67                 dp[i][j]=((sum[i-1][j-1]-sum[i-1][max(j-m,0ll)])%mod+mod)%mod;
68                 sum[i][j]=(sum[i][j-1]+dp[i][j])%mod;
69                 //cout<<dp[i][j]<<endl;
70             }
71             ans=(ans+dp[i][n]*C(d,i)%mod)%mod;
72         }
73         //cout<<dp[1][n]<<endl;
74         //for(int i=2;i<=min(d,n);i++) ans=(ans+dp[i][n]*C(d,i)%mod)%mod;
75         printf("%lld\n",ans%mod);
76     }
77 }
View Code

 

Guess you like

Origin www.cnblogs.com/leom10/p/11221286.html