zoukankan      html  css  js  c++  java
  • Luogu5307 [COCI2019] Mobitel 【数论分块】【递推】

    题目分析:

    对于向上取整我们总有,$lceil frac{lceil frac{n}{a} ceil}{b} ceil = lceil frac{n}{a*b} ceil$这个不难想到。

    然后朴素的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
    ",f[m][num]);
    38     return 0;
    39 }
  • 相关阅读:
    HDU2013 蟠桃记
    HDU2012 素数判定
    I00030 Grades conversion
    HDU2011 多项式求和
    HDU2009 求数列的和
    HDU2005 第几天?【日期计算】
    HDU2004 成绩转换
    HDU2006 求奇数的乘积
    HDU2007 平方和与立方和【序列处理】
    HDU2010 水仙花数【进制+趣味程序】
  • 原文地址:https://www.cnblogs.com/Menhera/p/10974045.html
Copyright © 2011-2022 走看看