• wenbao与数位dp


     套路题,在数字上面进行dfs,要点是剪枝(记忆的状态不同,效果大不一样)

     ---------------------------------------------------

    http://acm.hdu.edu.cn/showproblem.php?pid=2089

     1 #include <iostream>
     2 #include <string.h>
     3 using namespace std;
     4 int n, m, num[20], dp[20][2];
     5 int d(int pos, int pre, int st, bool limi){
     6     if(pos == -1) return 1;
     7     if(!limi && dp[pos][st] != -1) return dp[pos][st];
     8     int up = limi ? num[pos] : 9;
     9     int sum = 0;
    10     for(int i = 0; i <= up; ++i){
    11         if(pre == 6 && i == 2) continue;
    12         if(i == 4) continue;
    13         sum += d(pos-1, i, i == 6, limi && i == up);
    14     }
    15     if(!limi) dp[pos][st] = sum;
    16     return sum;
    17 }
    18 int f(int x){
    19     int pos = 0;
    20     while(x){
    21         num[pos++] = x%10;
    22         x /= 10;
    23     }
    24     num[pos] = 0;
    25     return d(pos-1, 1, 0, true);
    26 }
    27 int main(){
    28     memset(dp, -1, sizeof(dp));
    29     while(~scanf("%d%d", &n, &m)){
    30         if(n == 0 && m == 0) break;
    31         printf("%d
    ", f(m) - f(n-1));
    32     }
    33     return 0;
    34 }

    ---------------------------------------------------

    http://acm.hdu.edu.cn/showproblem.php?pid=6156

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 using namespace std;
     5 typedef long long ll;
     6 ll dp[40][40][40][2], L, R;
     7 int num[40],temp[40], l, r;
     8 ll dfs(int bas, int start,int cur,bool state,bool fp){
     9     if(cur<0)
    10         return state;
    11     if(!fp&&dp[bas][start][cur][state]!=-1)
    12         return dp[bas][start][cur][state];
    13     int fpmax = fp ? num[cur] : (bas-1);
    14     ll ret = 0;
    15     for(int i = 0; i <= fpmax; i++){
    16         temp[cur] = i;
    17         if(start == cur && i == 0)
    18             ret += dfs(bas, start-1, cur-1, state, fp && i==fpmax);
    19         else if(state && cur < (start+1)/2)
    20             ret += dfs(bas, start, cur-1, temp[start-cur]==i, fp&&i==fpmax);
    21         else
    22             ret+=dfs(bas, start, cur-1, state, fp&&i==fpmax);
    23     }
    24     if(!fp) 
    25         dp[bas][start][cur][state] = ret;
    26     return ret;
    27 }
    28 ll f(ll n){
    29     ll sum = 0, nn = n;
    30     for(int i = l; i <= r; ++i){
    31         int len=0;
    32         sum += nn;
    33         n = nn;
    34         while(n){
    35             num[len++] = n%i;
    36             n /= i;
    37         }
    38         num[len]=0;
    39         sum += dfs(i, len-1, len-1, 1, 1)*(i-1);
    40     }
    41     return sum;
    42 }
    43 int main(){
    44     int T;
    45     scanf("%d", &T);
    46     int res = 1;
    47     memset(dp,-1,sizeof(dp));
    48     while(T--){
    49         scanf("%lld%lld%d%d", &L, &R, &l, &r);
    50         printf("Case #%d: %lld
    ", res++, f(R)-f(L-1));
    51     }
    52     return 0;
    53 }

    -------------------------------------------------

    http://codeforces.com/problemset/problem/855/E

     1 #include <iostream>
     2 #include <string.h>
     3 using namespace std;
     4 #define ll long long
     5 ll n, m, num[66], dp[66][66][1025];
     6 ll d(ll cnt, ll sum, ll pos, ll st, bool pre, bool limi) {
     7     if(pos == -1) return sum == 0;
     8     if(!pre && !limi && dp[cnt][pos][sum] != -1) return dp[cnt][pos][sum];
     9     ll up = limi ? num[pos] : cnt - 1;
    10     ll summ = 0;
    11     for(ll i = 0; i <= up; ++i) {
    12         ll M;
    13         if(pre && i == 0) M = sum;
    14         else M = sum ^ (1LL << i);
    15         summ += d(cnt, M, pos - 1, i, pre && i == 0, limi && i == up);
    16     }
    17     if(!pre && !limi) dp[cnt][pos][sum] = summ;
    18     return summ;
    19 }
    20 ll f(ll cnt, ll x) {
    21     ll pos = 0;
    22     while(x) {
    23         num[pos++] = x % cnt;
    24         x /= cnt;
    25     }
    26     num[pos] = 0;
    27     return d(cnt, 0, pos - 1, 0, true, true);
    28 }
    29 int main() {
    30     memset(dp, -1, sizeof(dp));
    31     ll t, x;
    32     ll l, r;
    33     scanf("%lld", &t);
    34     while(t--) {
    35         scanf("%lld%lld%lld", &x, &l, &r);
    36         printf("%lld
    ", f(x, r) - f(x, l - 1));
    37     }
    38     return 0;
    39 }

    --------------------------------------------------

    -----------------------------------------------------

    -------------------------------------------------------

    只有不断学习才能进步!

  • 相关阅读:
    前端基础之CSS
    前端基础之HTML(三)
    前端基础之HTML(二)
    前端基础之HTML(一)
    面向对象总结
    内置函数总结
    函数部分总结
    文件操作总结
    基础数据类型总结
    python基础知识总结
  • 原文地址:https://www.cnblogs.com/wenbao/p/7693498.html
Copyright © 2020-2023  润新知