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

luogu4443 coci 2017 Dajave

luogu P5052 [COCI2017-2018#7] Go

Luogu4433:[COCI2009-2010#1] ALADIN(类欧几里德算法)

题解 luogu P4415 [COCI2006-2007#2] KOLONE