• 【BZOJ4069】[APIO2015] 巴厘岛的雕塑(按位枚举+DP)


    点此看题面

    大致题意: 让你把一个序列分成若干段((Ale)段数(le B)),使得每一段元素之和按位取或的结果最小。

    前言

    完了完了,感觉自己的思维已经僵化了,看到这种题第一反应二分+贪心,然后就掉坑里出不来了。

    而且我似乎就陷在贪心里了,之后无论推到哪一步,第一反应就是如何贪心。。。

    更有甚者,我连题目都没读完整,居然没看见这是一道二合一。。。

    按位枚举+(DP)

    首先,这种二进制运算的题目我们应该从高到低枚举每一位,使得较高位尽量小。

    则我们需要考虑如何验证,这就可以想到一个(DP)

    (f_{i,j})表示(DP)到第(i)位,共分为(j)段是否可行。则我们枚举之前的一个位置(k),若(sum_{x=k+1}^ia_x)当前这一位以及之前已确定为答案的位不含(1),就可以从(f_{k,j-1})转移得来。((sum a_x)可以前缀和预处理)

    虽然这样显然过不了全部数据,但最后一个子任务(A=1)。。。

    因此,我们只要设(f_i)表示(DP)到第(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 2000
    #define LL long long
    #define Gmin(x,y) (x>(y)&&(x=(y)))
    using namespace std;
    int n,Mn,Mx,a[N+5];LL s[N+5];
    namespace SmallSituation//针对小数据
    {
    	int f[N+5][N+5];
    	I bool Check(Con LL& Ban)//Ban表示禁止位
    	{
    		RI i,j,k;for(f[0][0]=i=1;i<=n;++i) for(j=1;j<=Mx;++j)
    			for(f[i][j]=k=0;k^i;++k) if(!((s[i]-s[k])&Ban)&&f[k][j-1]) {f[i][j]=1;break;}
    		for(i=Mn;i<=Mx;++i) if(f[n][i]) return 1;return 0;
    	}
    }
    namespace NoLowerBound//针对无下界的数据
    {
    	int f[N+5];
    	I bool Check(Con LL& Ban)//和上面的转移方式几乎一样
    	{
    		RI i,k;for(i=1;i<=n;++i)
    			for(f[i]=Mx+1,k=0;k^i;++k) !((s[i]-s[k])&Ban)&&Gmin(f[i],f[k]+1);//不含禁止位才能转移
    		return f[n]<=Mx;
    	}
    }
    int main()
    {
    	RI i;for(scanf("%d%d%d",&n,&Mn,&Mx),i=1;i<=n;++i) scanf("%d",a+i),s[i]=s[i-1]+a[i];//统计前缀和
    	LL ans=0,Ban=0;for(i=42;~i;--i) Ban|=1LL<<i,//从高到低枚举每一位,先禁止掉当前位
    		!(Mn^1?SmallSituation::Check(Ban):NoLowerBound::Check(Ban))&&(ans|=1LL<<i,Ban^=1LL<<i);
    	return printf("%lld",ans),0;//输出答案
    }
    
  • 相关阅读:
    附加数据库 对于 服务器“00-PC”失败
    SQL 语句转换格式函数Cast、Convert
    sql语句:union
    ISNULL-sqlserver语句
    SQL中的CASE WHEN语句
    SQL SELECT INTO 语句
    Sql语句中IN等方面的用法
    combobox的不常用的方法和将txt文本内容加到textbox中显示
    程序员:“菜鸟”和“大神”差距在哪
    过劳死离我们有多远?
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ4069.html
Copyright © 2020-2023  润新知