最近码力略渣,敲题总是WA,考虑不全,还是要加强码力
本题是一道组合数学统计问题
问的是给一个序列,求他在所有波浪序列中排名第几
注意各种限制,各种特判.....
#include <cstdio>
#include <cstring>
#include <iostream>
typedef long long ll;
using namespace std;
char s[1000];
ll dp[10][20][2];
int tot,a[20];
ll solve(int f,int llen,int dir){
int i;
ll ans=1;
for(i=2;i<=18-llen;i++)
ans+=dp[f][i][dir];
return ans;
}
ll dfs(int pos,int doing){
if(pos==tot)return 0;
ll ans=0,i;
if(pos>=2)ans++;
if(pos==0){
for(i=1;i<a[pos];i++){
ans+=solve(i,pos,1);
ans+=solve(i,pos,0);
ans-=10;
}
}
else if(pos==1){
for(i=1;i<a[pos];i++){
if(i==a[pos-1])continue;
if(i>a[pos-1])ans+=solve(i,pos,1);
else ans+=solve(i,pos,0);
ans--;
}
}
else if(pos>=2){
if(doing==0) i=a[pos-1]+1;else i=1;
for(;i<a[pos];i++){
if(doing==0){
ans+=solve(i,pos,1);
}
else ans+=solve(i,pos,0);
}
}
int next;
if(a[pos+1]>a[pos])next=0;
else next=1;
return ans+=dfs(pos+1,next);
}
void init(){
int i,j,len;
memset(dp,0,sizeof(dp));
for(i=1;i<9;i++)
dp[i][2][0]=9-i;
for(i=2;i<=9;i++)
dp[i][2][1]=i-1;
for(len=3;len<=18;len++){
for(i=1;i<9;i++){
for(j=i+1;j<=9;j++)
dp[i][len][0]+=dp[j][len-1][1];
}
for(i=2;i<=9;i++){
for(j=1;j<i;j++)
dp[i][len][1]+=dp[j][len-1][0];
}
}
}
int main(){
//freopen("a.txt","r",stdin);
//freopen("c.txt","w",stdout);
int t,T,len;
int i,j;
scanf("%d\n",&T);
init();
for(t=1;t<=T;){
gets(s);
tot=0;
len=strlen(s);
if(len==0)continue;
t++;
for(i=j=0;i<len;){
a[j]=s[i]-'0';
i++;
while(s[i]==' ')i++;
tot++;
j++;
}
cout<<dfs(0,-1)<<endl;
}
return 0;
}