zoukankan      html  css  js  c++  java
  • 【HDU 5898】oddeven number

    题目

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5898
    \([l,r]\) 内有多少个数字满足该数字连续的偶数有奇数个,连续的奇数有偶数个。

    思路

    考虑数位 dp。设 \(f[i][j][0/1]\) 表示现在处理到第 \(i\) 位,有连续 \(j\) 个奇数 / 偶数的方案数。
    转移的时候枚举这一位选择的数即可。注意最后一位时要判断最后连续的几个数是否合法。

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    
    const int N=20;
    int Q,bit[N];
    ll ql,qr,f[N][N][2];
    
    // 第 x 位,有连续 cnt 个奇偶性位 num 的数,是否要有上界要求,是否有前导零。
    ll dfs(int x,int cnt,int num,bool flag,bool lead)
    {
    	if (!x) return (cnt&1)^num;
    	if (!flag && !lead && f[x][cnt][num]!=-1) return f[x][cnt][num];
    	ll ret=0;
    	int up=flag?bit[x]:9;
    	for (int i=0;i<=up;i++)
    	{
    		if (!i && lead)
    			ret+=dfs(x-1,0,1,0,1);
    		else
    		{
    			if ((i&1)==num)
    				ret+=dfs(x-1,cnt+1,num,flag&(i==bit[x]),0);
    			if ((i&1)!=num && (cnt&1)!=num)
    				ret+=dfs(x-1,1,num^1,flag&(i==bit[x]),0);
    		}
    	}
    	if (!flag && !lead) f[x][cnt][num]=ret;
    	return ret;
    }
    
    ll solve(ll num)
    {
    	memset(f,-1,sizeof(f));
    	int cnt=0;
    	for (;num;num/=10)
    		bit[++cnt]=num%10;
    	return dfs(cnt,0,1,1,1);
    }
    
    int main()
    {
    	scanf("%d",&Q);
    	for (int i=1;i<=Q;i++)
    	{
    		scanf("%lld%lld",&ql,&qr);
    		printf("Case #%d: %lld\n",i,solve(qr)-solve(ql-1));
    	}
    	return 0;
    }
    
  • 相关阅读:
    个人报告04
    个人报告03
    构建之法阅读笔记07
    个人报告02
    第二次冲刺个人报告01
    第二阶段个人总结5
    第十三周学习进度情况
    第二阶段个人总结4(5.28)
    第二阶段个人总结3(5.27)
    课堂作业之找小水王
  • 原文地址:https://www.cnblogs.com/stoorz/p/13784424.html
Copyright © 2011-2022 走看看