Luogu5307 [COCI2019] Mobitel 数论分块递推
Posted menhera
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu5307 [COCI2019] Mobitel 数论分块递推相关的知识,希望对你有一定的参考价值。
题目分析:
对于向上取整我们总有,$\lceil \frac\lceil \fracna \rceilb \rceil = \lceil \fracna*b \rceil$这个不难想到。
然后朴素的dp很容易想到,用上面的式子优化一下就行了。
代码:
1 // luogu-judger-enable-o2 2 #include<bits/stdc++.h> 3 using namespace std; 4 5 const int mod = 1e9+7; 6 7 int f[350][5020]; 8 int a[350][350]; 9 int rem[5020],pep[1020000]; 10 int n,m,k,num; 11 12 int main() 13 scanf("%d%d%d",&n,&m,&k); 14 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); 15 int lst = 0; 16 for(int i=1;i<=k;i++) 17 int now = k/i + (k%i != 0); 18 if(now != lst) rem[++num] = i,pep[now] = num; 19 lst = now; 20 21 f[1][1] = 1; 22 for(int i=1;i<=n;i++) 23 for(int j=1;j<=m;j++) 24 for(int ku=num;ku>=1;ku--) 25 if(!f[j][ku] && !f[j-1][ku]) continue; 26 int dem = f[j][ku]; 27 f[j][ku] = 0; 28 int ham = rem[ku]; 29 if(1ll*ham*a[i][j] >= k) ham = k; 30 else ham = a[i][j]*ham; 31 ham = pep[k/ham+(k%ham!=0)]; 32 f[j][ham] += dem; if(f[j][ham] >= mod) f[j][ham] -= mod; 33 f[j][ham] += f[j-1][ku]; if(f[j][ham] >= mod) f[j][ham]-=mod; 34 35 36 37 printf("%d\n",f[m][num]); 38 return 0; 39
以上是关于Luogu5307 [COCI2019] Mobitel 数论分块递推的主要内容,如果未能解决你的问题,请参考以下文章
[Luogu5181][COCI2009]GENIJALAC
Luogu_4329 [COCI2006-2007#1] Bond
luogu P5052 [COCI2017-2018#7] Go