hdu5898 odd-even number

/*
求符合連續奇數序列的長度爲偶數,連續偶數序列的長度爲奇數的個數
數位dp,dp[i][j]表示當前在第i位,前一位數的狀態爲j的個數,j有5種,0表示全部都是0,
1:奇數長度爲奇,2:奇數長度爲偶,3:偶數長度爲奇,4:偶數長度爲偶
從高位開始,枚舉所有可能的數,limit=0表示沒有限制,可以選0——9,limit=1表示有限制,
只能選0——num[pos],dp數組保存無限制並且dp!=-1的情況
*/


#include <stdio.h>
#include <string.h>


#define LL long long
int num[20];
LL dp[20][5];


LL dfs(int pos,int limit,int status){
if(pos<1){
if(status==2||status==3)
return 1;
else
return 0;
}


if(!limit&&dp[pos][status]!=-1)
return dp[pos][status];


int end=limit?num[pos]:9;
LL ans=0;


for(int i=0;i<=end;i++){
if(!status){
if(!i)
ans+=dfs(pos-1,0,0);
else if(i & 1)
ans+=dfs(pos-1,limit&&i==end,1);
else
ans+=dfs(pos-1,limit&&i==end,3);
}
else{
if(status == 1){
if(i & 1)
ans+=dfs(pos-1,limit&&i==end,2);
}
else if(status == 2){
if(i & 1)
ans+=dfs(pos-1,limit&&i==end,1);
else
ans+=dfs(pos-1,limit&&i==end,3);
}
else if(status==3){
if(i&1)
ans+=dfs(pos-1,limit&&i==end,1);
else
ans+=dfs(pos-1,limit&&i==end,4);
}
else{
if(!(i&1))
ans+=dfs(pos-1,limit&&i==end,3);
}
}
}
dp[pos][status]=ans;
return ans;
}


LL solve(LL x){
memset(dp,-1,sizeof(dp));
int len=0;
while(x){
num[++len]=x%10;
x/=10;
}
return dfs(len,1,0);
}


int main(){
int t;
scanf("%d",&t);
for(int c=1;c<=t;c++){
LL l,r;
scanf("%lld%lld",&l,&r);
printf("Case #%d: %lld\n",c,solve(r)-solve(l-1));
}
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章