BZOJ1111 : [POI2007]四进制的天平Wag

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;
}

  

posted @ 2015-07-02 16:52  Claris  阅读(703)  评论(4编辑  收藏  举报