zoukankan      html  css  js  c++  java
  • bzoj 1111 [POI2007]四进制的天平Wag 数位Dp

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

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 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。
     
     
    题解:%%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 }
  • 相关阅读:
    重写MembershipProvider实现自己的身份验证
    重写MembershipProvider用于事务处理(一)
    ASP.NET 2.0中GridView无限层复杂表头的实现
    用好VS2005之扩展membership服务
    ASP.NET2.0角色控制和管理
    asp.net2.0自带的Provider源码下载
    ASP.NET2.0上传EXCEL文件到gridview中显示
    一次编辑GridView 的所有行
    重写MembershipProvider用于事务处理(二)
    创建表头固定,表体可滚动的GridView
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8982429.html
Copyright © 2011-2022 走看看