您的位置:首页 > 其它

HDU 5898 odd-even number(数位dp)

2016-09-21 15:08 323 查看
题目链接

题意就是,数位是奇数的连续的长度是偶数,数位是偶数的连续的长度是奇数,比如 2,4,6, 8,11,13,15,17。。

直接数位dp, 加一个z标识,是不是前缀都是0。

dp[i][s][len]:第i位是奇数还是偶数,以及连续的长度。

#include <bits/stdc++.h>
#define LL long long
using namespace std;
#define cl(a,b) memset(a,b,sizeof(a))
const int maxn = 25;

int bit[maxn];
LL dp[maxn][2][maxn];
LL dfs(int i,int s,int len,bool e,bool z) {
if(i == 0)return (s && len%2==0 || !s && len%2==1);
if(!e && dp[i][s][len]!=-1) return dp[i][s][len];
LL ans = 0;
int u = e?bit[i]:9;
for(int d=0; d<=u; d++) {
if(z) {
if(d==0) ans += dfs(i-1,0,0,e&&u==d,1);
else ans += dfs(i-1,d&1,1,e&&d==u,0);
} else {
if(d&1) {
if(s) ans += dfs(i-1,1,len+1,e&&d==u,0);
else if(len%2==1) ans += dfs(i-1,1,1,e&&d==u,0);
} else {
if(!s) ans += dfs(i-1,0,len+1,e&&d==u,0);
else if(len%2==0) ans += dfs(i-1,0,1,e&&d==u,0);
}
}
}
return e?ans:dp[i][s][len]=ans;
}

LL f(LL num) {
int len = 0;
while(num) {
bit[++len] = num%10;
num /= 10;
}
return dfs(len,0,0,1,1);
}

int main() {
int T, cas = 1;
LL L,R;
scanf("%d", &T);
while(T--) {
scanf("%lld%lld",&L,&R);
cl(dp,-1);
printf("Case #%d: %lld\n",cas++, f(R) - f(L-1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: