zoukankan      html  css  js  c++  java
  • [POI2007]四进制的天平Wag

    Description
    Mary准备举办一个聚会,她准备邀请很多的人参加她的聚会。并且她准备给每位来宾准备一些金子作为礼物。为了不伤及每个人的脸面,每个人获得的金子必须相同。Mary将要用一个天平来称量出金子。她有很多的砝码,所有砝码的质量都是4的幂。Mary将金子置于左边并且将砝码置于右盘或者两个盘。她希望每次称量都使用最少的砝码。并且,他希望,每次都用不同的称量方法称出相同质量的金子。对于给定的质量n,Mary希望知道最少需要用多少个砝码可以完成称量,并且想知道用这么多个砝码一共有多少种方式进行称量。

    Input
    输入文件仅包含一个整数,表示Mary希望给每个人的金子的质量。(1<=n<=10^1000)

    Output
    输出文件仅包含一个整数,表示一共可能的称量方式对10^9的模。

    Sample Input
    166

    Sample Output
    3

    HNIT
    一共有三种方式称量出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。


    首先把n转成4进制,然后开始从低位向高位DP。
    f[i]表示不向下一位借位,g[i]表示向下一位借位,f[i],g[i]都要带上两个参数,为当前用了多少个数和匹配种数。转移方程如下:
    f[i]=merge(f[i-1]+T[i],g[i-1]+1+T[i]);
    g[i]=mergr(f[i-1]+4-T[i],g[i-1]+3-T[i]);
    (注:借到的一位不算在当前第i位上,f[i]记录的只是4^i,不论正负)

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int p=1e9;
    const int N=1e4;
    const int digit=4;
    const int base=1e4;
    char s[N+10];
    struct Bignum{
    	int v[N+10],len;
    	Bignum(){len=1,memset(v,0,sizeof(v));}
    	void read(){
    		scanf("%s",s);
    		int t=strlen(s),tim=1;
    		len=(t-1)/digit+1;
    		for (int i=0,j=t-1;i<j;i++,j--)	swap(s[i],s[j]);
    		for (int i=0;i<t;i++){
    			v[i/digit]+=(s[i]-'0')*tim,tim*=10;
    			if (tim==base)	tim=1;
    		}
    	}
    	void write(){
    		printf("%d",v[len-1]);
    		for (int i=len-2;~i;i--)	printf("%0*d",digit,v[i]);
    		putchar('
    ');
    	}
    }A,Zero;
    int operator %(Bignum x,int y){
    	for (int i=x.len;i;i--)	x.v[i-1]+=x.v[i]%y*base;
    	return x.v[0]%y;
    }
    Bignum operator /(Bignum &x,int y){
    	for (int i=x.len;~i;i--)	x.v[i-1]+=x.v[i]%y*base,x.v[i]/=y;
    	while (!x.v[x.len]&&x.len)	x.len--;
    	x.len++;
    	return x;
    }
    bool operator ==(const Bignum &x,const Bignum &y){
    	if (x.len!=y.len)	return 0;
    	for (int i=0;i<=x.len;i++)	if (x.v[i]!=y.v[i])	return 0;
    	return 1;
    }
    bool operator !=(const Bignum &x,const Bignum &y){return !(x==y);}
    struct Dp{
    	int x,y;
    	Dp(){}
    	Dp(int _x,int _y){x=_x,y=_y;}
    }f[N+10],g[N+10];
    Dp min(const Dp &a,const Dp &b){return a.x<b.x?a:b;}
    Dp operator +(const Dp &a,int b){return Dp(a.x+b,a.y);}
    Dp operator +(const Dp &a,const Dp &b){return a.x==b.x?Dp(a.x,(a.y+b.y)%p):min(a,b);}
    int T[N+10];
    int main(){
    	int tot=1;
    	A.read();
    	while (A!=Zero)	T[tot++]=A%4,A=A/4;
    	f[0]=Dp(0,1),g[0]=Dp(inf,0);
    	for (int i=1;i<=tot;i++){
    		f[i]=(f[i-1]+T[i])+(g[i-1]+(T[i]+1));
    		g[i]=(f[i-1]+(4-T[i]))+(g[i-1]+(3-T[i]));
    	}
    	printf("%d
    ",f[tot].y);
    	return 0;
    }
    
  • 相关阅读:
    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details
    Visual Studio断点调试, 无法监视变量, 提示无法计算表达式
    ASP.NET MVC中MaxLength特性设置无效
    项目从.NET 4.5迁移到.NET 4.0遇到的问题
    发布网站时应该把debug设置false
    什么时候用var关键字
    扩展方法略好于帮助方法
    在基类构造器中调用虚方法需谨慎
    ASP.NET MVC中商品模块小样
    ASP.NET MVC中实现属性和属性值的组合,即笛卡尔乘积02, 在界面实现
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/8945344.html
Copyright © 2011-2022 走看看