HDu 3565 Bi-peak Number数ビットdp
3395 ワード
タイトルリンク:
http://acm.hdu.edu.cn/showproblem.php?pid=3565
テーマ:
各数字が先に増減した数をピーク数(桁数が等3より大きく、第1位がゼロではない)と呼び、その後、2つのピーク数がつながって1つのbi-peak数であり、2つの数の間のbi-peak数の各数字の和の最大値を求める.
問題解決の考え方:
数ビットdp,dp[i][j][k]は現在の後にiビットがあることを示し,jは前のビットの数字を示し,kはピークとの状態関係を示す.
k=0は前面がゼロであることを示し、k=1は前面にちょうど1つが第1のピークの上り坂にあることを示し、k=2は前面に少なくとも2つが第1のピークの上り坂にあることを示し、k=3は第1のピークの下り坂にあることを示す
k=4は前方に2番目のピークの上り坂があることを示し、k=5は前方に少なくとも2つのピークが2番目のピークの上り坂にあることを示し、k=6は2番目のピークの下り坂にあることを示す.
ピーク数のビット数は少なくとも3であり、第1のビットはゼロではないことに注意してください.
コード:
http://acm.hdu.edu.cn/showproblem.php?pid=3565
テーマ:
各数字が先に増減した数をピーク数(桁数が等3より大きく、第1位がゼロではない)と呼び、その後、2つのピーク数がつながって1つのbi-peak数であり、2つの数の間のbi-peak数の各数字の和の最大値を求める.
問題解決の考え方:
数ビットdp,dp[i][j][k]は現在の後にiビットがあることを示し,jは前のビットの数字を示し,kはピークとの状態関係を示す.
k=0は前面がゼロであることを示し、k=1は前面にちょうど1つが第1のピークの上り坂にあることを示し、k=2は前面に少なくとも2つが第1のピークの上り坂にあることを示し、k=3は第1のピークの下り坂にあることを示す
k=4は前方に2番目のピークの上り坂があることを示し、k=5は前方に少なくとも2つのピークが2番目のピークの上り坂にあることを示し、k=6は2番目のピークの下り坂にあることを示す.
ピーク数のビット数は少なくとも3であり、第1のビットはゼロではないことに注意してください.
コード:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<list>
#include<queue>
#define eps 1e-6
#define INF (1<<30)
#define PI acos(-1.0)
using namespace std;
#define ll unsigned __int64
int dp[30][15][7];
// 0 0, 1 ,2 ,3
// 4 5 6
int aa[30],bb[30];
int dfs(int cur,int last,int flag,int aflag,int bflag)
{
if(!cur) //
return (flag==6)?0:-1;
if(!aflag&&!bflag&&dp[cur][last][flag]!=-1)
return dp[cur][last][flag];
int Min=aflag?aa[cur]:0; //
int Max=bflag?bb[cur]:9; //
int res=-1;
for(int i=Min;i<=Max;i++)
{
int status=0;
if(flag==0&&i)
status=1;
else if(flag==1)
{
if(i>last)
status=2;
else
status=-1;
}
else if(flag==2)
{
if(i<last)
status=3;
else if(i==last)
status=-1;
else
status=2;
}
else if(flag==3)
{
if(i>last)
status=4;
else if(i==last)
{
if(i)
status=4;
else
status=-1;
}
else
status=3;
}
else if(flag==4)
{
if(i>last)
status=5;
else
status=-1;
}
else if(flag==5)
{
if(i<last)
status=6;
else if(i==last)
status=-1;
else
status=5;
}
else if(flag==6)
{
if(i<last)
status=6;
else
status=-1;
}
if(status!=-1)
{
int temp=dfs(cur-1,i,status,aflag&&i==Min,bflag&&i==Max);
if(temp!=-1)
res=max(res,i+temp);
}
}
if(!aflag&&!bflag)
dp[cur][last][flag]=res;
return res;
}
int main()
{
int t;
scanf("%d",&t);
memset(dp,-1,sizeof(dp));
for(int ca=1;ca<=t;ca++)
{
ll a,b;
scanf("%I64u%I64u",&a,&b);
int pos=0;
while(b)
{
++pos;
aa[pos]=a%10;
a/=10;
bb[pos]=b%10;
b/=10;
}
int ans=dfs(pos,0,0,1,1);
printf("Case %d: ",ca);
if(ans!=-1)
printf("%d
",ans);
else
printf("0
");
}
return 0;
}