数位dp

Round Numbers POJ - 3252(数位dp)

不打扰是莪最后的温柔 提交于 2019-12-17 02:59:48
题目 The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone’ (also known as ‘Rock, Paper, Scissors’, ‘Ro, Sham, Bo’, and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can’t even flip a coin because it’s so hard to toss using hooves. They have thus resorted to “round number” matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both “round numbers”, the first cow wins, otherwise the second cow wins. A positive integer N is said to be a

POJ3252——数位dp

白昼怎懂夜的黑 提交于 2019-12-15 00:05:32
数位DP,难点在处理前导0. #include <cstdio> #include<iostream> using namespace std; typedef long long ll; const int N = 1e5+7; int di[50]; ll dp[50][100];//二进制下 ,0-第i位,1的个数小于等于j的数 的个数 ll dfs(int len,int num,bool limit,bool head)//当前位len;;当前位之前 1的个数减去0的个数;;是否达到上界;;是否是前导0 { if(len==0)return 1; int now=(len-num)/2; //注意:有前导0和无前导0是不一样的。 // 比如我们dp[3][1], 有: 100 010 001 ,有前导0-> 100 10 1 //有前导会使前面的0自动消去,导致0/1数量无法统计(强行统计会重复)。所以干脆我们就加一个限制条件 //只有非前导0才进行计算 if(!limit&&dp[len][now]&&!head)return dp[len][now]; int upl=limit?di[len]:1; ll ans=0; for(int i=0;i<=upl;i++) { //在这里区分前导0和非前导0对后续的影响 if(head) { int tp=num+(i=

关于数位dp

喜你入骨 提交于 2019-12-14 07:00:30
上周学了数位dp,本来想上周周末写一下这个总结,怎奈没有安排上时间 安排 @ TOC 关于题目小结 关于所做过题目的总结以及一些个人想法。 不要62 HDU - 2089 这个题目给我的收获是知道怎么去处理出现连续的两个位数和出现单个位数的特殊情况。 对于这种连续两个位数的情况直接使ispre是上一位是x,i是下一位。 单个位数的话限制条件就是i。 然后,直接上模板做就可以了。比如这题。 HDU - 3555 Bomb 还有这个题目 HDU - 3652 关于这道题目限制条件就是出现13和数不能被13整除的个数。 又get了一个新的知识,就是对于被某个数整除的情况, 对于被整除, modx=mod*10+i;//这个可以求出每一个数字。 简单 说到着,这些数位dp简单题目学了数位dp的人肯定都可以做,因为(这个dp的束缚条件比较少,也比较好处理。) 我不想就仅仅如此,我还想更上一层楼,那么对于这个,还需要自己做更多的题目。 ll dfs ( int pos , int mod , int have , int limit ) { int modx , havex ; if ( pos == 0 ) { return mod == 0 && have == 2 ; } if ( ! limit && dp [ pos ] [ mod ] [ have ] != - 1 )

习题:神奇的NIM游戏(数位DP&状压)

醉酒当歌 提交于 2019-12-14 04:20:18
题目 思路 神仙数位DP题目 最开始想到的是三进制状压 每一位表示这个数不变,增加还是减少 \(dp_{k,s,i,0/1}\) 表示考虑到第k位,状态为s,正在考虑第i个数,第k的异或和为0/1 这样一来, 时间复杂度就为 \(O(32*n*3^n)\) 很明显瞬间爆炸 但是我们仔细思考增加和减少 如果这个数的比他高的位数已经将后面的值整体赋值 如果是增加 那么代价就是 \(2^i\) 如果是减少呢? 代价也是 \(2_i\) 也就是说我们的状态可以转换成二进制 但是我们需要多增加一位来表示这一位是否被比他高的位数整体赋值 笔者称其为约束 \(dp_{k,s,i,0/1,0/1}\) 表示考虑到第k位,状态位s,第i个数,第s位的异或和为0/1,第i个数的第k位是否被约束 首先我们考虑DP的转移,可以发现,当前第k位的状态只与第k+1位的状态有关 也就是k我们可以滚动 第i个数也是完全没有必要的 直接修改就行了 笔者太菜直接贴了STD的代码 代码 #include <cstdio> #include <cstring> #include <algorithm> #define rep(i, x, y) for (int i = (x), _ = (y); i <= _; ++i) #define down(i, x, y) for (int i = (x), _ = (y); i

HDU - 3652 - B-number(数位DP)

会有一股神秘感。 提交于 2019-12-06 23:47:29
链接: https://vjudge.net/problem/HDU-3652 题意: A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task is to calculate how many wqb-numbers from 1 to n for a given integer n. 思路: 数位DP,记录前面的余数,和前一位的数,和是否已经存在13.四维DP。 如果不记录前一位的值,可能出现无法判断13是否存在。 代码: // #include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<vector> #include<string.h> #include<set> #include<queue> #include<algorithm> #include<math.h> using namespace std; typedef

HDU - 4734 - F(x) (数位DP)

心已入冬 提交于 2019-12-06 23:46:37
链接: https://vjudge.net/problem/HDU-4734 题意: For a decimal number x with n digits (A nA n-1A n-2 ... A 2A 1), we define its weight as F(x) = A n * 2 n-1 + A n-1 * 2 n-2 + ... + A 2 * 2 + A 1 * 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A). 思路: F的最大值在5000以内。 考虑每次a都是不同的,为了减少mem的时间,我们让记录他的和变成记录当前值和F(a)的差,这样就具有通用性。不用每次的mem时间。 代码: // #include<bits/stdc++.h> #include<iostream> #include<cstdio> #include<vector> #include<string.h> #include<set> #include<queue> #include<algorithm> #include<math.h> using

HDU - 3709 - Balanced Number(数位DP)

删除回忆录丶 提交于 2019-12-06 23:44:34
链接: https://vjudge.net/problem/HDU-3709 题意: A balanced number is a non-negative integer that can be balanced if a pivot is placed at some digit. More specifically, imagine each digit as a box with weight indicated by the digit. When a pivot is placed at some digit of the number, the distance from a digit to the pivot is the offset between it and the pivot. Then the torques of left part and right part can be calculated. It is balanced if they are the same. A balanced number must be balanced with the pivot at some of its digits. For example, 4139 is a balanced number with pivot fixed at 3. The

POJ - 3252 - Round Numbers(数位DP)

拥有回忆 提交于 2019-12-06 23:39:17
链接: https://vjudge.net/problem/POJ-3252 题意: The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can't even flip a coin because it's so hard to toss using hooves. They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins, otherwise the second cow wins.

数位dp

烂漫一生 提交于 2019-12-06 23:27:25
//hdu2089 #include "cstdio" #include "cstring" #include "iostream" #include "algorithm" using namespace std; int cont; long long dig[10001]; long long dp[20][2][2]; int dfs(int pos,int six,int flag){ if (pos<0)return 1; long long ans=0; if (dp[pos][six][flag]!=-1)return dp[pos][six][flag]; for (int i = 0; i <= 9;i++){ if (i>dig[pos]&&flag==1)break; if (i==2&&six==1)continue; if (i==4)continue; ans=ans+dfs(pos-1,i==6,flag&&i==dig[pos]); } return dp[pos][six][flag]=ans; } long long s(long long x){ if (x<0)return 0; memset(dp,-1,sizeof(dp)); cont=0; while (x){ dig[cont++]=x%10; x=x/10; } return

HDU - 3555 - Bomb(数位DP)

你离开我真会死。 提交于 2019-12-06 15:24:01
链接: https://vjudge.net/problem/HDU-3555 题意: The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence "49", the power of the blast would add one point. Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them? 思路: 考虑没有49的数,用a-掉就行。 Dp(i, j) i位置为j时的值。 因为计算了0要多加1. 代码: #include<bits/stdc++.h> using namespace std; typedef long long LL; const int MOD = 1e9+7; const int MAXN = 1e6+10