light OJ 1140

题目大意:

m到n的范围内要写几个0


进爷说数位dp概率比较小,那今天就到这里先告一段落了,以后有时间再回来吧

题目列表的话这为大牛的蛮好的http://blog.csdn.net/xianxingwuguan1/article/details/18955791

补充一个题目,杭电的5632

然后要记住,一定要是lld,I64dWA了我好多次


给出代码:


#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> using namespace std; typedef long long ll; ll n, m; ll bit[25]; ll dp[25][3][50]; //pos是位数,pre表示第一位有没有放下去,不然就是前导0,status表示是有几个0 //first是用来排除0,00,000,0000这些状况 ll dfs(int pos, int pre, int status, int flag){ //printf("status = %d\n", status); if (pos <= 0){ if (pre == 0) return status + 1; return status; } if (!flag && pre && dp[pos][pre][status] != -1) return dp[pos][pre][status]; ll last = flag ? bit[pos] : 9; ll res = 0; for (int i = 0; i <= last; i++){ ll ind = status; if (pre == 0){ if (i == 0) res += dfs(pos - 1, 0, ind, flag && i == last); else res += dfs(pos - 1, 1, ind, flag && i == last); } else { if (i == 0) res += dfs(pos - 1, 1, ind + 1, flag && i == last); else res += dfs(pos - 1, 1, ind, flag && i == last); } } if (!flag && pre == 1){ //printf("res = %d\n", res); dp[pos][pre][status] = res; } return res; } ll cal(ll x){ memset(bit, 0, sizeof(bit)); int cnt = 0; while (x){ bit[++cnt] = x % 10; x /= 10; } return dfs(cnt, 0, 0, 1); } int main(){ int t; scanf("%d", &t); memset(dp, -1, sizeof(dp)); int cnt = 0; while (t--){ scanf("%lld%lld", &m, &n); printf("Case %d: %lld\n", ++cnt, cal(n) - cal(m - 1)); } return 0; } </iostream></cstring></algorithm></cstdio>

你可能感兴趣的:(light OJ 1140)