HDOJ3565 Bi-peak Number
| 
 题目链接:HDOJ3565 题意:首先定义了一个peak number,是没有前导0的,存在某一个数位,比左右两边的数字都大的数 然后Bi-peak number,是两个peak number的数位相连 分析样例就能够得到这个题的坑点,很友善的题 样例1是只有5个数位,要分成Bi-peak number,至少要6位,abcdef,其中b>a,b>c,e>d,e>f 样例2是想要分解的话,后面那个数有前导0 样例3简单 这个题充分的体现了自己数位DP不熟练 不会根据题目,来灵活的设计DP状态和转移 dp【pos】【state】【pre】是设计的状态 pos和pre很好理解,那么state如何定义呢? 因为是Bi-peak,所以需要标记我当前找的这个数处在那个阶段,是往第一个peak走,还是从第二个peak下来,都需要记录 所以: 0表示前导0 1表示第一个上升坡 2表示第一个顶点 3表示第一个下降坡 4表示第二个上升坡 5表示第二个顶点 6表示第二个下降坡 这个题是求最大值,不是求区间个数 所以不会满足区间的减法 所以用到一个新的技巧,把【X,Y】区间中的两端X,Y都数位分解放到dfs中去 记录两个变量,分别是前导的0和后置的flag 每次在数位枚举的时候,从可用的最小枚举到可用的最大 状态转移只能严格的从前一个转到后一个,因为必须按照数位的大小来排 特殊情况就是可以浪费如:123212321 可以上坡下坡时间长一点,数位多一点,这就是在山上多一个判断 细节见代码 #include<map>
#include<set>
#include<math.h>
#include<time.h>
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<stdio.h>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define ll rt<<1
#define rr rt<<1|1
#define LL long long
#define ULL unsigned long long
#define maxn 1050
#define maxnum 1000050
#define eps 1e-6
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define MOD 1000000007
bool vis[25][10][15];
int dp[25][10][15];
int digitlow[25],digitup[25];
int dfs(int pos,int state,int pre,bool lowbound,bool upbound){
	if (state==0&&pos<6) return -1;
	if (pos==0) return state==5?0:-1;
	if (lowbound&&upbound&&vis[pos][state][pre])
		return dp[pos][state][pre];
	int Min=lowbound?0:digitlow[pos];
	int Max=upbound?9:digitup[pos];
	int ret=-1,temp;
	for(int i=Min;i<=Max;i++)
		switch(state){
			case 0:temp=dfs(pos-1,(i==0?0:1),i,lowbound||i>Min,upbound||i<Max);
			if (temp!=-1)
				ret=max(ret,temp+i);
			break;
			case 1:
			if (i>pre){
				temp=dfs(pos-1,1,upbound||i<Max);
				if (temp!=-1)
					ret=max(ret,temp+i);
				temp=dfs(pos-1,2,temp+i);
			}
			break;
			case 2:
			if (i<pre){
				temp=dfs(pos-1,3,temp+i);
			}
			break;
			case 3:
			if (i<pre){
				temp=dfs(pos-1,temp+i);
			}
			if (i){
				temp=dfs(pos-1,4,temp+i);
			}
			break;
			case 4:
			if (i>pre){
				temp=dfs(pos-1,5,temp+i);
			}
			break;
			case 5:
			if (i<pre){
				temp=dfs(pos-1,temp+i);
			}
			break;
		}
	if (lowbound&&upbound){
		vis[pos][state][pre]=true;
		dp[pos][state][pre]=ret;
	}
	return ret;
}
int calc(unsigned long long x,unsigned long long y){
	memset(digitlow,sizeof(digitlow));
	memset(digitup,sizeof(digitup));
	int len1=0,len2=0;
	while(x){
		digitlow[++len1]=x%10;
		x/=10;
	}
	while(y){
		digitup[++len2]=y%10;
		y/=10;
	}
	return dfs(len2,0);
}
int main(){
	//input;
	int T;
	unsigned long long x,y;
	scanf("%d",&T);
	for(int Case=1;Case<=T;Case++){
		scanf("%I64u%I64u",&x,&y);
		int ans=calc(x,y);
		printf("Case %d: %dn",Case,ans==-1?0:ans);
	}
	return 0;
}
(编辑:91站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! | 


