zoukankan      html  css  js  c++  java
  • Codeforces Gym100623J:Just Too Lucky(数位DP)

    http://codeforces.com/gym/100623/attachments

    题意:问1到n里面有多少个数满足:本身被其各个数位加起来的和整除。例如120 % 3 == 0,111 % 3 == 0,都算。

    思路:老是写不出数位DP。。。

    因为n最大为12位,所以取模的数最大可以是9*12 == 108,因此枚举这个模。

    dfs记录的状态有:pos, sum, mod, remain, flag。

    pos代表枚举到第几位,

    sum代表数位之和,

    mod代表当前枚举的模,

    remain代表当前枚举的数,(做不出来主要昨天这里没考虑好,12 % 3和120 % 3是一样的结果)

    flag代表前面是否达到上限。

    然后最后判定的时候只要remain == 0 && mod == sum就是可行的状态。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 #define N 15
     5 #define M 110
     6 int dp[N][M][M][M], bit[N];
     7 
     8 LL dfs(int pos, int sum, int mod, int remain, int flag) {
     9     if(!pos) return sum == mod && remain == 0;
    10     if(~dp[pos][sum][remain][mod] && flag) return dp[pos][sum][remain][mod];
    11     int d = flag ? 9 : bit[pos];
    12     LL ans = 0;
    13     for(int i = 0; i <= d; i++)
    14         ans += dfs(pos - 1, sum + i, mod, (remain * 10 + i) % mod, flag || i != d);
    15     if(flag) dp[pos][sum][remain][mod] = ans;
    16     return ans;
    17 }
    18 
    19 LL solve(LL n) {
    20     int len = 0;
    21     while(n) { bit[++len] = n % 10; n /= 10; }
    22     LL ans = 0;
    23     for(int i = 1; i <= 108; i++)
    24         ans += dfs(len, 0, i, 0, 0);
    25     return ans;
    26 }
    27 
    28 int main() {
    29     freopen("just.in", "r", stdin);
    30     freopen("just.out", "w", stdout);
    31     memset(dp, -1, sizeof(dp));
    32     LL n; cin >> n;
    33     cout << solve(n) << endl;
    34     return 0;
    35 }
  • 相关阅读:
    Android性能优化典范
    通过命令行连接oracle数据库/进入sql plus
    eclispe 出现超内存错误
    eclipse 重装了tomcat后配置路径
    dorado listener属性
    dorado问题查询&快捷键重命名
    dorado spring知识补充
    Eclipse导入包的快捷键
    dorado抽取js
    dorado中的creationType选择类型
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6650047.html
Copyright © 2011-2022 走看看