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; } (编辑:92站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |