题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4734
解题心得:这个题主要就是 d p dp dp状态不好表示,并不能被一眼就看出来,这里可以用 d p [ i ] [ j ] dp[i][j] dp[i][j]表示低位 i i i个数与 s u m _ A sum\_A sum_A的差小于 j j j的有多少个。其实这个不是很容易想到, d p dp dp真的是好灵活啊。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5010;
int dp[15][maxn], a, b, tot;
vector <int> ve;
void get_tot() {
int x = a, p = 1;
tot = 0;
while(x) {
tot += p*(x%10);
x/=10;
p <<= 1;
}
}
void get_ve() {
ve.clear();
while(b) {
ve.push_back(b%10);
b /= 10;
}
}
int dfs(int pos, int sum, int limit) {
if(pos == -1) return sum <= tot;
if(sum > tot) return 0;
if(!limit && dp[pos][tot-sum] != -1) return dp[pos][tot-sum];
int up = limit ? ve[pos] : 9;
int cnt = 0;
for(int i=0;i<=up;i++) {
cnt += dfs(pos - 1, sum + i*(1<<pos), limit && (i == ve[pos]));
}
if(!limit) dp[pos][tot-sum] = cnt;
return cnt;
}
int main() {
// freopen("1.in.txt", "r", stdin);
int t; scanf("%d", &t);
int T = t;
memset(dp, -1, sizeof dp);
while(t--) {
scanf("%d%d", &a, &b);
get_tot();
get_ve();
printf("Case #%d: %d\n", T-t, dfs(ve.size()-1, 0, 1));
}
}