http://acm.fzu.edu.cn/problem.php?pid=2109
题意:找出区间[l,r]内满足奇数位的数字大于相邻偶数位数字的个数。
典型的数位dp了,记录一下当前位是奇数位还是偶数位。
状态设计为到当前位为(奇数还是偶数的条件下上一位数字为x的)满足条件的 个数。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 20;
int dp[MAX][MAX][ 2];
int digit[MAX];
int dfs( int pos, int pre, bool c, bool limit, bool check)
{
if(!pos)
{
if(!check) return 1;
else return 0;
}
if(check) return 0;
if(!limit&&~dp[pos][pre][c]&&!check) return dp[pos][pre][c];
int end=limit?digit[pos]: 9; int ans= 0;
for( int i= 0;i<=end;i++)
{
if(c&&pre<=i) ans+=dfs(pos- 1,i,c^ 1,limit&&(end==i),check);
else if(!c&&pre>=i) ans+=dfs(pos- 1,i,c^ 1,limit&&(end==i),check);
else ans+=dfs(pos- 1,i,c^ 1,limit&&(end==i),check|| 1);
}
if(!limit&&!check) dp[pos][pre][c]=ans;
return ans;
}
int solve( int n)
{
int cur= 0;
while(n)
{
digit[++cur]=n% 10;
n/= 10;
}
return dfs(cur, 9, false, true, false);
}
int main()
{
int cas,L,R;
scanf( " %d ",&cas);
memset(dp,- 1, sizeof(dp));
while(cas--)
{
scanf( " %d %d ",&L,&R);
printf( " %d\n ",solve(R)-solve(L- 1));
}
}
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 20;
int dp[MAX][MAX][ 2];
int digit[MAX];
int dfs( int pos, int pre, bool c, bool limit, bool check)
{
if(!pos)
{
if(!check) return 1;
else return 0;
}
if(check) return 0;
if(!limit&&~dp[pos][pre][c]&&!check) return dp[pos][pre][c];
int end=limit?digit[pos]: 9; int ans= 0;
for( int i= 0;i<=end;i++)
{
if(c&&pre<=i) ans+=dfs(pos- 1,i,c^ 1,limit&&(end==i),check);
else if(!c&&pre>=i) ans+=dfs(pos- 1,i,c^ 1,limit&&(end==i),check);
else ans+=dfs(pos- 1,i,c^ 1,limit&&(end==i),check|| 1);
}
if(!limit&&!check) dp[pos][pre][c]=ans;
return ans;
}
int solve( int n)
{
int cur= 0;
while(n)
{
digit[++cur]=n% 10;
n/= 10;
}
return dfs(cur, 9, false, true, false);
}
int main()
{
int cas,L,R;
scanf( " %d ",&cas);
memset(dp,- 1, sizeof(dp));
while(cas--)
{
scanf( " %d %d ",&L,&R);
printf( " %d\n ",solve(R)-solve(L- 1));
}
}