• URAL 2052 Physical Education(数位DP)


    题目链接:https://vjudge.net/contest/254142#problem/G

    参考题解:https://blog.csdn.net/zearot/article/details/47984379

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define LL __int128
      5 #define ull unsigned long long
      6 #define mst(a,b) memset((a),(b),sizeof(a))
      7 #define mp(a,b) make_pair(a,b)
      8 #define pi acos(-1)
      9 #define pii pair<int,int>
     10 #define pb push_back
     11 const int INF = 0x3f3f3f3f;
     12 const double eps = 1e-6;
     13 const int MAXN = 1e5 + 10;
     14 const int MAXM = 2e6 + 10;
     15 const ll mod = 1e9 + 7;
     16 
     17 int f[15][100], dig[15];
     18 
     19 void init() {
     20     mst(f, 0);
     21     f[0][0] = 1;
     22     for(int i = 1; i <= 10; i++)
     23         for(int j = 0; j <= i * 9; j++)
     24             for(int k = 0; k <= min(9, j); k++)
     25                 f[i][j] += f[i - 1][j - k];
     26 }
     27 
     28 int findall(int pos,int sum,bool limit) {
     29     if(!limit || !pos) return f[pos][sum];
     30     int ans = 0, mx = min(dig[pos], sum);
     31     for(int i = 0; i <= mx; i++)
     32         ans += findall(pos - 1,sum - i,limit && i == dig[pos]);
     33     return ans;
     34 }
     35 
     36 int shu[15];
     37 
     38 void findd(int pos,int sum,int rnk,bool limit) {
     39     if(!pos) return ;
     40     if(!limit) {
     41         int mx = min(9, sum);
     42         for(int i = 0; i <= mx; i++) {
     43             if(f[pos - 1][sum - i] < rnk) rnk -= f[pos - 1][sum - i];
     44             else {
     45                 shu[pos] = i;
     46                 findd(pos - 1,sum - i,rnk,limit);
     47                 return ;
     48             }
     49         }
     50     } else {
     51         int mx = min(dig[pos], sum);
     52         for(int i = 0; i <= mx; i++) {
     53             int temp = findall(pos - 1,sum - i,i == dig[pos]);
     54             if(temp < rnk) rnk -= temp;
     55             else {
     56                 shu[pos] = i;
     57                 findd(pos - 1,sum - i,rnk,i == dig[pos]);
     58                 return ;
     59             }
     60         }
     61     }
     62 }
     63 
     64 int main()
     65 {
     66 #ifdef local
     67     freopen("data.txt", "r", stdin);
     68 //    freopen("data.txt", "w", stdout);
     69 #endif
     70     init();
     71     int n,len = 0;
     72     scanf("%d",&n);
     73     while(n) {
     74         dig[++len] = n % 10;
     75         n /= 10;
     76     }
     77     int ans = 0,sum = 0;
     78     for(int i = 1; i <= len * 9; i++) {
     79         int num = findall(len,i,true);
     80         if(!num) continue;
     81         int l = 1, r = num, num1;
     82         bool flag = false;
     83         while(l <= r) {
     84             int mid = (l + r) >> 1;
     85             findd(len,i,mid,true);
     86             num1 = 0;
     87             for(int j = len; j >= 1; j--) {
     88                 if(!num1 && !shu[j]) continue;
     89                 num1 = num1 * 10 + shu[j];
     90             }
     91             if(sum + mid > num1) l = mid + 1;
     92             else if(sum + mid < num1) r = mid - 1;
     93             else {
     94                 flag = true;
     95                 break;
     96             }
     97         }
     98         if(flag) ans++;
     99         sum += num;
    100     }
    101     printf("%d
    ",ans);
    102     return 0;
    103 }
  • 相关阅读:
    计算机网络 其他1
    C++ part9
    C++ part8
    操作系统 part5
    C++ part7
    MyXls导出Excel的各种设置
    C# excel操作
    Castle
    C# Keycode对照表
    IEnumerable.Select和SelectMany的区别
  • 原文地址:https://www.cnblogs.com/scaulok/p/9683006.html
Copyright © 2020-2023  润新知