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
  • 相关阅读:
    django框架的models
    图像的特征提取
    laravel框架学习
    机器学习--Classifier comparison
    java中的静态变量---static
    初次编程经历
    TERSUS笔记员工信息513-Tersus表格中勾选框升级处理
    TERSUS笔记员工信息512-Tersus勾选框全选和全不选的三种设定方法(转载+补充)
    TERSUS笔记员工信息511-Mysql查询
    TERSUS笔记员工信息510-css文字超出显示
  • 原文地址:https://www.cnblogs.com/i-caigou-TT/p/14368968.html
Copyright © 2011-2022 走看看