BZOJ1111 : [POI2007]四進位制的天平Wag

Claris發表於2015-07-02

POI2007完結撒花~

 

首先將n轉化為四進位制,從低位到高位DP

f[i]表示這一位不向下一位借位

g[i]表示這一位向下一位借位,但借的那個不算在i

f[0]=0,g[0]=inf

f[i]=merge(f[i-1]+b[i],g[i-1]+b[i]+1)

g[i]=merge(f[i-1]+4-b[i],g[i-1]+3-b[i])

 

#include<cstdio>
#include<cstring>
#define N 1670
struct E{
  int x,y;
  E(){}
  E(int _x,int _y){x=_x,y=_y;}
  inline E operator+(int _x){return E(x+_x,y);}
  inline E operator+(E b){return x==b.x?E(x,(y+b.y)%1000000000):(x<b.x?E(x,y):b);}
}f[N],g[N];
int l,n,i,a[N],b[N];char s[N];
int main(){
  for(scanf("%s",s),l=std::strlen(s),i=1;i<=l;i++)a[i]=s[l-i]-'0';
  while(l){
    for(i=l,a[0]=0;i;i--)a[i-1]+=(a[i]&3)*10,a[i]>>=2;
    for(b[++n]=a[0]/10;l&&!a[l];l--);
  }
  for(f[0]=E(0,1),g[0]=E(N,0),n++,i=1;i<=n;i++)f[i]=(f[i-1]+b[i])+(g[i-1]+(b[i]+1)),g[i]=(f[i-1]+(4-b[i]))+(g[i-1]+(3-b[i]));
  return printf("%d",f[n].y),0;
}

  

相關文章