zoukankan      html  css  js  c++  java
  • 【BZOJ1110】[POI2007] 砝码(进制分解)

    点此看题面

    大致题意:(n)个背包和(m)个砝码,每个背包有一定的重量限制,而砝码两两之间重量都成倍数关系。求最多能把几个砝码装入背包。

    前言

    (Jan 29th)刷题计划(5/6),算法标签:贪心。

    一道有技巧的贪心,一道挺有趣的题目。

    进制分解

    考虑题目中“砝码两两之间重量都成倍数关系”这句话肯定有猫腻,必然要以它为入手点。

    将砝码按重量排序并去重后,易知每一个砝码重量至少是前一个砝码的两倍,因此砝码重量的种数总共也只有(log_2(10^9)≈30)种,是非常少的。

    设排序去重后第(i)种砝码重量为(a_i),个数为(b_i)

    我们定义一个特殊的进制,其中第(i)位的位权是(a_i)

    然后我们把背包的容量都按照这种特殊的进制进行进制分解,然后分每一位加在一起。注意,加的过程中不能进位,因为每个背包是独立的。

    最后,我们贪心地从小到大枚举每一种砝码。

    对于第(i)种砝码,我们操作(b_i)次,每次将第(i)位减(1)。若减成了负数,则去向更高位借位。若无法再借,就说明无法再加砝码。

    注意,第(i+1)位的(1)退到第(i)位,会变成(frac{a_{i+1}}{a_i})

    具体实现详见代码。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    using namespace std;
    int n,m,k,s[N+5],a[N+5],b[N+5],p[N+5];
    I bool Dec(CI x)//将第x位减1
    {
    	RI i;for(i=x;i<=k&&!p[i];++i);if(i>k) return 0;//如果借不到,返回0
    	for(--p[i--];i>=x;--i) p[i]+=a[i+1]/a[i]-1;return 1;//借位,返回1
    }
    int main()
    {
    	RI i,j,t=0;for(scanf("%d%d",&n,&m),i=1;i<=n;++i) scanf("%d",s+i);
    	for(i=1;i<=m;++i) scanf("%d",a+i);sort(a+1,a+m+1);//排序
    	for(i=1;i<=m;++i) a[i]^a[i-1]?(a[++k]=a[i],b[k]=1):(++b[k]);//去重,同时统计每种砝码的个数
    	for(i=1;i<=n;++i) for(j=k;j;--j) p[j]+=s[i]/a[j],s[i]%=a[j];//进制分解
    	for(i=1;i<=k;++i) for(j=1;j<=b[i];++j) if(Dec(i)) ++t;else goto End;//枚举砝码尝试放入
    	End:return printf("%d",t),0;//输出答案
    }
    
  • 相关阅读:
    UVALive4973 CERC2010A Ardenia
    HDU4116 Fruit Ninja (2011 Asia ChengDu Regional Contest)
    POJ1030 Rating
    HDU2471 2008 Asia Regional Hangzhou History of Languages
    UVA12304_2D Geometry 110 in 1!
    UVALive4974 CERC2010B Beasts
    2012CSU_ACM集训中期检测 简要题解
    关于ACM,2010开始的一些故事
    UVA12302 NinePoint Circle
    System.Web.HttpRequestValidationException:解决方法
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ1110.html
Copyright © 2011-2022 走看看