zoukankan      html  css  js  c++  java
  • codeforces 401D. Roman and Numbers 数位dp

    题目链接

    给出一个<1e18的数, 求将他的各个位的数字交换后, 能整除m的数的个数。

    用状态压缩记录哪个位置的数字已经被使用了, 具体看代码。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define pb(x) push_back(x)
     4 #define ll long long
     5 #define mk(x, y) make_pair(x, y)
     6 #define lson l, m, rt<<1
     7 #define mem(a) memset(a, 0, sizeof(a))
     8 #define rson m+1, r, rt<<1|1
     9 #define mem1(a) memset(a, -1, sizeof(a))
    10 #define mem2(a) memset(a, 0x3f, sizeof(a))
    11 #define rep(i, a, n) for(int i = a; i<n; i++)
    12 #define ull unsigned long long
    13 typedef pair<int, int> pll;
    14 const double PI = acos(-1.0);
    15 const double eps = 1e-8;
    16 const int mod = 1e9+7;
    17 const int inf = 1061109567;
    18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    19 int digit[20], m, cnt;
    20 ll dp[1<<18][101];
    21 ll dfs(int s, int num) {            //s是当前状态, num是模m剩余的数
    22     if(num==0&&s==0)
    23         return 1;
    24     if(~dp[s][num])
    25         return dp[s][num];
    26     int used[10];
    27     mem(used);
    28     ll ret = 0;
    29     for(int i = 0; i<cnt; i++) {
    30         if(!(s&(1<<i)))             //如果这一位已经被使用了就直接continue
    31             continue;
    32         if(used[digit[i]])
    33             continue;
    34         used[digit[i]] = 1;
    35         ret += dfs(s^(1<<i), (num*10+digit[i])%m);
    36     }
    37     return dp[s][num] = ret;
    38 }
    39 int main()
    40 {
    41     int num[12];
    42     mem(num);
    43     mem1(dp);
    44     ll n;
    45     cin>>n>>m;
    46     while(n) {
    47         digit[cnt++] = n%10;
    48         n/=10;
    49     }
    50     ll ans = 0;
    51     ll s = (1<<cnt)-1;          //初始全都没有被使用
    52     for(int i = 0; i<cnt; i++) {
    53         if(digit[i]) {
    54             if(num[digit[i]])       //某一位上的数不能够重复计数
    55                 continue;
    56             num[digit[i]] = 1;
    57             ans += dfs(s^(1<<i), digit[i]%m);       //s^(1<<i)说明第i位被使用了
    58         }
    59     }
    60     cout<<ans<<endl;
    61     return 0;
    62 }
  • 相关阅读:
    static
    crontab
    coco2d-x 纹理研究
    2048-AI程序算法分析
    如何利用SVN合并代码
    Cocos2d-x 对于中文的支持-----iconv库
    cocos2d-x 2.2 资源更新AssetsManager例子代码
    防止手机游戏衰老的方法
    游戏开发博客
    网络游戏同步法则
  • 原文地址:https://www.cnblogs.com/yohaha/p/5048638.html
Copyright © 2011-2022 走看看