zoukankan      html  css  js  c++  java
  • CodeForces 215E Periodical Numbers 数位DP

    这题做了有好几天了,终于过了= =

    完全不懂网上题解的递推写法,只能自己用记忆化搜索瞎搞,总算是搞出来了。

    具体策略就是记忆化搜索的时候用一个tmp数组记录最前面len个的值,然后后面的数字必须要和前len相同。

    但是麻烦的是这样子会有重复,想了一个很挫的写法就是枚举算出恰好长度为ll并且循环节长度为l的数字的个数,然后全部记录下来,从小到大依次减去重复的。

    真是挫。。。sad

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 70;
    int lim[maxn],len;
    int tmp[maxn];
    LL f[maxn][maxn];
    
    void getlim(LL num) {
        len = 0;
        memset(lim,0,sizeof(lim));
        while(num) {
            lim[len++] = num % 2;
            num /= 2;
        }
    }
    
    LL dfs(int now,int l,int ll,int first,int bound) {
        if(now == 0) {
            return first % l == 0 && first / l >= 2 && first == ll;
        }
        int m = bound ? lim[now - 1] : 1;
        if(first != -1 && !bound && f[now][first] != -1) return f[now][first] ;
        LL ret = 0;
        for(int i = 0;i <= m;i++) {
            if(i && first == -1) first = now;
            if(first == -1) ret += dfs(now - 1,l,ll,-1,bound && i == m);
            else {
                int pos = first - now;
                tmp[pos] = i;
                if(pos < l) ret += dfs(now - 1,l,ll,first,bound && i == m);
                else if(tmp[pos % l] == i) {
                    ret += dfs(now - 1,l,ll,first,bound && i == m);
                }
            }
        }
        if(first != -1 && !bound) f[now][first] = ret;
        return ret;
    }
    
    LL solve(LL num) {
        getlim(num);
        LL ret = 0,cnt[maxn][maxn];
        memset(cnt,0,sizeof(cnt));
        for(int i = 1;i <= len / 2 + 1;i++) {
            for(int j = len;j >= 1;j--) {
                memset(f,-1,sizeof(f));
                cnt[i][j] = dfs(len,i,j,-1,1);
            }
        }
        for(int i = 2;i <= len / 2;i++) {
            for(int j = 1;j < i;j++) if(i % j == 0) {
                for(int k = i * 2;k <= len;k++) if(k % i == 0) {
                    cnt[i][k] -= cnt[j][k];
                }
            }
        }
        for(int i = 1;i <= len / 2;i++) {
            for(int j = 1;j <= len;j++) {
                ret += cnt[i][j];
            }
        }
        return ret;
    }
    
    int main() {
        LL a,b; cin >> a >> b;
        cout << solve(b) - solve(a - 1) << endl;
        return 0;
    }
    

      

  • 相关阅读:
    使用jsonEditor打造一个复杂json编辑器
    【原创】一次“诡异”的容器Unix Socket通信问题分析
    【原创】Ingress-Nginx-Controller的Metrics监控源码改造简析
    IDEA+DevTools实现热部署功能
    ElementUI按需引入各种组件
    vue-cli4.0更新后怎样将eslint关闭
    Mysql修改字段名、修改字段类型
    博客搬家CSDN
    如何优雅的处理Restful
    java系列之注解
  • 原文地址:https://www.cnblogs.com/rolight/p/3893949.html
Copyright © 2011-2022 走看看