1111: [POI2007]四进制的天平Wag
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 302 Solved: 201
[Submit][Status][Discuss]
Description
Mary准备举办一个聚会,她准备邀请很多的人参加她的聚会。并且她准备给每位来宾准备一些金子作为礼物。为了不伤及每个人的脸面,每个人获得的金子必须相同。Mary将要用一个天平来称量出金子。她有很多的砝码,所有砝码的质量都是4的幂。Mary将金子置于左边并且将砝码置于右盘或者两个盘。她希望每次称量都使用最少的砝码。并且,他希望,每次都用不同的称量方法称出相同质量的金子。对于给定的质量n,Mary希望知道最少需要用多少个砝码可以完成称量,并且想知道用这么多个砝码一共有多少种方式进行称量。
Input
输入文件仅包含一个整数,表示Mary希望给每个人的金子的质量。(1<=n<=10^1000)
Output
输出文件仅包含一个整数,表示一共可能的称量方式对10^9的模。
Sample Input
166
Sample Output
3
样例解释
一共有三种方式称量出166。166=64+64+16+16+4+1+1。166=256-64-16-16+4+1+1。166=256-64-16-4-4-1-1。
样例解释
一共有三种方式称量出166。166=64+64+16+16+4+1+1。166=256-64-16-16+4+1+1。166=256-64-16-4-4-1-1。
题解:%%claris
首先将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])
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 7 #define ll long long 8 #define mod 1000000000 9 #define N 2000 10 11 #define Wb putchar(' ') 12 #define We putchar(' ') 13 #define rg register int 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 19 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 20 return x*f; 21 } 22 inline void write(ll x) 23 { 24 if(x<0) putchar('-'),x=-x; 25 if (x==0) putchar(48); 26 int num=0;char c[20]; 27 while(x) c[++num]=(x%10)+48,x/=10; 28 while(num) putchar(c[num--]); 29 } 30 31 int n; 32 int a[N],b[N]; 33 char s[N]; 34 struct Node 35 { 36 int x,y; 37 Node(){} 38 Node(int _x,int _y){x=_x,y=_y;} 39 friend Node operator+(Node x,int a){return Node(x.x+a,x.y);} 40 friend Node operator+(Node x,Node y) 41 { 42 return x.x==y.x?Node(x.x,(x.y+y.y)%mod):(x.x<y.x?x:y); 43 } 44 }f[N],g[N]; 45 46 int main() 47 { 48 scanf("%s",s);int len=strlen(s); 49 for (int i=1;i<=len;i++) 50 a[i]=s[len-i]-'0'; 51 while(len) 52 { 53 a[0]=0; 54 for (rg i=len;i>=1;i--) 55 a[i-1]+=(a[i]&3)*10,a[i]>>=2; 56 for (b[++n]=a[0]/10;len&&!a[len];len--); 57 } 58 f[0]=Node(0,1),g[0]=Node(N,0),n++; 59 for (rg i=1;i<=n;i++) 60 f[i]=(f[i-1]+b[i])+(g[i-1]+(b[i]+1)), 61 g[i]=(f[i-1]+(4-b[i]))+(g[i-1]+(3-b[i])); 62 write(f[n].y); 63 }