zoukankan      html  css  js  c++  java
  • 洛谷 P4127[AHOI2009]同类分布

    这道题的状态其实很好想,dp[x][st][sum]表示前x位原数是st和是sum的个数。

    问题是原数太大了,状态开不下。

    因为这道题我们实际上要的是st%sum,而sum最大只有172,所以不妨对st取个模,如果st%mod==0,sum%mod==0,那么st%mod==0.

    因为这里模数最多只到sum最大值,所以直接枚举模数对每一个模数做一遍数位DP然后求和。

    这里注意,以前因为状态相同,所以DP的值可以重复利用,但是这里的值里面隐含了取模的条件,所以每次DP都要重新初始化。

    下附代码:

     1 #include<bits/stdc++.h>
     2 #define ll long long
     3 using namespace std;
     4 ll dp[19][173][173],dim[20];
     5 ll dfs(int x,int st,int sum,int jb,int mod){
     6     if (!x){
     7         if (sum==mod && st==0) return 1;
     8         else return 0;
     9     }
    10     if (!jb && dp[x][sum][st]!=-1) return dp[x][sum][st];
    11     ll ret=0;
    12     int maxn=9;
    13     if (jb) maxn=dim[x];
    14     for (int i=0; i<=maxn; i++){
    15         ret+=dfs(x-1,(st*10+i)%mod,sum+i,(jb==1 && i==maxn),mod);
    16     }
    17     if (!jb) return dp[x][sum][st]=ret;
    18     return ret;
    19 }
    20 int main(){
    21     ll a,b;
    22     scanf("%lld%lld",&a,&b);
    23     a--;
    24     int len=0;
    25     while (a){
    26         dim[++len]=a%10;
    27         a/=10;
    28     }
    29     ll resl=0;
    30     for (int i=1; i<=9*len; i++){
    31         memset(dp,-1,sizeof(dp));
    32         resl+=dfs(len,0,0,1,i);
    33     }
    34     len=0;
    35     while (b){
    36         dim[++len]=b%10;
    37         b/=10;
    38     }
    39     ll resr=0;
    40     for (int i=1; i<=9*len; i++){
    41         memset(dp,-1,sizeof(dp));
    42         resr+=dfs(len,0,0,1,i);
    43     }
    44     printf("%lld",resr-resl);
    45 }
    View Code
  • 相关阅读:
    BZOJ1691: [Usaco2007 Dec]挑剔的美食家
    BZOJ1584: [Usaco2009 Mar]Cleaning Up 打扫卫生
    BZOJ3057: 圣主的考验
    BZOJ1770: [Usaco2009 Nov]lights 燈
    1710: [Usaco2007 Open]Cheappal 廉价回文
    「Poetize7」电话线路
    「Poetize6」Candle
    「Poetize5」水叮当的舞步
    解题:CF983A Finite or not
    解题:POI 2013 Triumphal arch
  • 原文地址:https://www.cnblogs.com/i-caigou-TT/p/14368968.html
Copyright © 2011-2022 走看看