数位DP貌似很弱,先切水的练练手~
HDU2089:点击打开链接
输出区间里面没有连续62,没有4的数字个数.
#include <bits/stdc++.h>
using namespace std;
long long n, m;
int bit[11], l;
int dp[11][2];
int dfs (int pos, bool f1, bool f2) {//当前的位数 前一个数是不是6 是不是可以取到9
if (pos == 0)
return 1;
if (f2 && dp[pos][f1] != -1) {
return dp[pos][f1];
}
int Max = (f2 ? 9 : bit[pos]), ans = 0;
for (int i = 0; i <= Max; i++) {
if (i == 4 || (f1 && i == 2))
continue;
ans += dfs (pos-1, i==6, f2 || i<Max);
}
if (f2)
dp[pos][f1] = ans;
return ans;
}
long long f (long long num) {
l = 0;
while (num) {
bit[++l] = num%10;
num /= 10;
}
return dfs (l, 0, 0);
}
int main () {
memset (dp, -1, sizeof dp);
while (cin >> n >> m && n+m) {
cout << f (m)-f (n-1) << endl;
}
return 0;
}
HDU3555:点击打开链接
1到n中没有连续49的数字个数.
同样
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
ull n;
int bit[11], l;
ull dp[22][2];
ull dfs (int pos, bool f1, bool f2) {//当前的位数 前一个数是不是4 是不是可以取到9
if (pos == 0)
return 1LL*1;
if (f2 && dp[pos][f1] != -1) {
return dp[pos][f1];
}
int Max = (f2 ? 9 : bit[pos]);
ull ans = 0;
for (int i = 0; i <= Max; i++) {
if (f1 && i == 9)
continue;
ans += dfs (pos-1, i==4, f2 || i<Max);
}
if (f2)
dp[pos][f1] = ans;
return ans;
}
long long f (long long num) {
l = 0;
while (num) {
bit[++l] = num%10;
num /= 10;
}
return dfs (l, 0, 0);
}
int main () {
//cout << (((ull)1<<63)-1) << endl;
memset (dp, -1, sizeof dp);
int t;
cin >> t;
while (t--) {
cin >> n;
cout << n-f (n)+1 << endl;
}
return 0;
}
UVA11361:点击打开链接
求所有位数和以及本身模k等于0的数的个数.
很相似,dfs的时候记录到当前位之前所有位数模k的余数m1和到当前位之前后面全部补0的余数m2,
转移方程就是dp(pos,m1,m2) = sigma {dp(pos-1, (m1-i)%k, (m2-i*10^pos-1)%k)}.
#include <bits/stdc++.h>
using namespace std;
long long n, m, mod;
int bit[11], l;
long long dp[12][111][111];
#define pow Pow
long long pow[13];
long long dfs (int pos, long long m1, long long m2, bool f2) {//当前的位数 所有的数位和模m余m1 后面的数字模m余m2 是不是可以取到9
if (pos == 0) {
if (m1 == 0 && m2 == 0)
return 1;
return 0;
}
if (f2 && dp[pos][m1][m2] != -1) {
return dp[pos][m1][m2];
}
long long Max = (f2 ? 9 : bit[pos]);
long long ans = 0;
for (long long i = 0; i <= Max; i++) {
ans += dfs (pos-1, (m1-i+mod)%mod, ((m2-i*pow[pos-1])%mod+mod)%mod, f2 || i < Max);
}
if (f2)
dp[pos][m1][m2] = ans;
return ans;
}
long long f (long long num) {
l = 0;
while (num) {
bit[++l] = num%10;
num /= 10;
}
if (l*9 < mod) {
return 1;//只能是0
}
return dfs (l, 0, 0, 0);
}
int main () {
pow[0] = 1;
for (long long i = 1; i <= 11; i++) pow[i] = pow[i-1]*10;
int t;
cin >> t;
while (t--) {
cin >> n >> m >> mod;
memset (dp, -1, sizeof dp);
cout << f (m) - f(n-1) << endl;
}
return 0;
}