HDU 4933 Miaomiao's Function(数位DP + 高精度)

题目连接 : http://acm.hdu.edu.cn/showproblem.php?pid=4933

题意 : 自己看吧,还是很容易理解的,就一个公式而已。

方法 : 比赛的时候想到两次数位DP:先对所有的数进行一次mod9 的数位DP,再得出的答案x为新的mod,再进行一次mod,后来写着写着发现似乎有点问题,对于answer = 0要特判,然后没想到好的方法,比赛就结束了。

赛后用java写了一发大数过的,对于题解中用多个大质数去判这种神奇的作法只能意会下了 , 貌似rand() 也行?

  1 import java.io.*;
  2 import java.util.*;
  3 import java.math.*;
  4
  5 public class Main {
  6
  7     /**
  8      * @param args
  9      */
 10     public static class Pair {
 11         BigInteger cnt, sum;
 12     }
 13
 14     public static BigInteger sum[][] = new BigInteger[105][3];
 15     public static BigInteger cnt[][] = new BigInteger[105][3];
 16     public static int bit[] = new int[105];
 17     public static boolean vis[][] = new boolean[105][3];
 18
 19     public static Pair dfs(int len, int dis, boolean fp) {
 20         //System.out.println(len + " " + s + " " + dis + " " + fp);
 21         Pair ret = new Pair();
 22         if (len == 0) {
 23             ret.cnt = BigInteger.ONE; ret.sum = BigInteger.ZERO;
 24             return ret;
 25         }
 26         if (fp == false && vis[len][dis] == true) {
 27             ret.cnt = cnt[len][dis];
 28             ret.sum = sum[len][dis];
 29             return ret;
 30         }
 31         int Max;
 32         BigInteger Sum = BigInteger.ZERO;
 33         BigInteger Cnt = BigInteger.ZERO;
 34         if (fp == true) Max = bit[len];
 35         else Max = 9;
 36         //System.out.println("Max = " + Max);
 37         for (int i = 0; i <= Max; i++) {
 38             if (i > 0) {
 39                 if (dis == 0 || dis == 1) {
 40                     ret = dfs(len-1, 2, fp==true&&i==Max);
 41                     Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum);
 42                     Sum = Sum.add(ret.cnt.multiply(BigInteger.valueOf(i)));
 43                 }else {
 44                     ret = dfs(len-1, 3-dis, fp==true&&i==Max);
 45                     Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum);
 46                     Sum = Sum.subtract(ret.cnt.multiply(BigInteger.valueOf(i)));
 47                 }
 48             }else {
 49                 if (dis == 0) {
 50                     ret = dfs(len-1, dis, fp==true&&i==Max);
 51                     Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum);
 52                 }else {
 53                     ret = dfs(len-1, 3-dis, fp==true&&i==Max);
 54                     Cnt = Cnt.add(ret.cnt); Sum = Sum.add(ret.sum);
 55                 }
 56             }
 57         }
 58         if (fp == false) {
 59             vis[len][dis] = true;
 60             sum[len][dis] = Sum;
 61             cnt[len][dis] = Cnt;
 62         }
 63         ret.cnt = Cnt; ret.sum = Sum;
 64         return ret;
 65     }
 66     public static BigInteger solve(BigInteger x) {
 67         if (x.equals(BigInteger.valueOf(-1))) return BigInteger.ZERO;
 68         String tmp = String.valueOf(x);
 69         for (int i = 0; i < tmp.length(); i++) {
 70             bit[i+1] = tmp.charAt(tmp.length() - i - 1) - ‘0‘;
 71         }
 72         return dfs(tmp.length(), 0, true).sum;
 73     }
 74     public static void main(String[] args) {
 75         // TODO Auto-generated method stub
 76         Scanner cin = new Scanner(System.in);
 77         int T = cin.nextInt();
 78         for (int cas = 1; cas <= T; cas++) {
 79             BigInteger L, R;
 80             L = cin.nextBigInteger();
 81             R = cin.nextBigInteger();
 82             BigInteger answer = solve(R).subtract(solve(L.subtract(BigInteger.ONE)));
 83             BigInteger Mod = answer;
 84             if (Mod.compareTo(BigInteger.ZERO) == 0) {
 85                 Mod = BigInteger.ZERO;
 86             }else {
 87                 Mod = Mod.mod(BigInteger.valueOf(9));
 88                 if (Mod.compareTo(BigInteger.ZERO) <= 0) Mod = Mod.add(BigInteger.valueOf(9));
 89             }
 90             if (Mod.equals(BigInteger.ZERO)) {
 91                 System.out.println("Error!");
 92             }else {
 93                 answer = answer.mod(Mod);
 94                 if (answer.compareTo(BigInteger.ZERO) < 0) answer = answer.add(Mod);
 95                 System.out.println(answer);
 96             }
 97         }
 98     }
 99
100 }

为什么java不能重载运算符呢!!!一个a = a.add(b) 写成 a.add(b)害的我差错查了1个小时啊! T T

HDU 4933 Miaomiao's Function(数位DP + 高精度)

时间: 2024-10-19 10:05:51

HDU 4933 Miaomiao's Function(数位DP + 高精度)的相关文章

[hdu 4933]Miaomiao&#39;s Function 数位DP+大数

Miaomiao's Function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 79    Accepted Submission(s): 18 Problem Description Firstly , Miaomiao define two functions f(x) , g(x): (K is the smallest

hdu 2089 不要62 (数位dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2089 思路:用变量记录吉利数,和最高位为2的吉利数还有不是吉利数的个数... code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int dp[10][3]; //dp[i][j] ,i表示位数,j表示状态<pre name="code"

HDU 4352 XHXJ&#39;s LIS 数位DP + 状压

由LIS的nlogn解法 可以得出最后统计数组中数的个数即为LIS的长度 这样就可以状压了 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <c

hdu 3709 Balanced Number (数位dp)

Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1871    Accepted Submission(s): 836 Problem Description A balanced number is a non-negative integer that can be balanced if a pi

HDU 4352 XHXJ&#39;s LIS 数位dp

题目链接:点击打开链接 题意: 一个数自身的最长子序列=每一位都是一个数字然后求的LIS 问区间内有多少个数 自身的最长子序列==k 思路: 因为自身的最长子序列至多=10,且由0~9组成,所以状压10个二进制表示0~9中哪些数字已经用过 dp[i][j] 表示长度为i的数字,最长子序列中出现的数字状态j的方法数.由于询问数=K,也存下来避免重复计算. #include <cstdio> #include <algorithm> #include <cstring> #

HDU 3709 Balanced Number 枚举+数位DP

枚举支点之后数位DP,注意姿势 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list&g

HDU 4588 Count The Carries 数位DP || 打表找规律

2013年南京邀请赛的铜牌题...做的很是伤心,另外有两个不太好想到的地方....a 可以等于零,另外a到b的累加和比较大,大约在2^70左右. 首先说一下解题思路. 首先统计出每一位的1的个数,然后统一进位. 设最低位为1,次低位为2,依次类推,ans[]表示这一位上有多少个1,那么有 sum += ans[i]/2,ans[i+1] += ans[i]/2; sum即为答案. 好了,现在问题转化成怎么求ans[]了. 打表查规律比较神奇,上图不说话. 打表的代码 #include <algo

HDU.4352.XHXJ&#39;s LIS(数位DP 状压 LIS)

题目链接 数位DP. 至于怎么求LIS,因为只有10个数,所以可以参照O(nlogn)求LIS的方法,状压记录状态. 每次加一个数和求LIS一样更新状态.最后状态中1的个数就是LIS的长度. //93MS 3004K #include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #define gc() getchar() typedef long long LL; c

HDU 6156 Palindrome Function 数位DP

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6156 题目描述: 求L~R所有的数的l~r进制的f(x), f(x) = 当前进制 如果回文串, f(x) = 1 其他情况 解题思路: 数位DP, 统计个数 , 需要作出改变的就是进制和回文 代码: #include <iostream> #include <cstdio> #include <string> #include <vector> #inclu