zoukankan      html  css  js  c++  java
  • CF981D Solution

    题目链接

    题解

    此题涉及异或运算且算法标签中有bitmasks,可以想到将答案分解为二进制(经典同类题目:老鼠试毒)。而分解后判断是否可以满足当前二进制位需要用到dp。因为异或运算不满足最优子问题,无法在一开始使用最优性dp,此处为可行性dp。

    状态:\(dp[i][j]\):前\(i\)本书放入\(j\)个书架是否(0/1)可以满足当前二进制位。

    初始值:\(dp[0][0]=1\),其余为\(0\)

    转移方程:无。枚举第\(i\)本书所在书架的左端点,如果该区间和满足当前及答案中全部二进制位,且转移来的状态合法,则当前状态合法。

    答案:合法二进制位权值和。

    此外利用贪心思想,二进制位需从大到小枚举,优先满足权值较大的。

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=55;
    int a[N],dp[N][N],sum[N];
    signed main()
    {
    	int n,k,ans=0,qwq;//qwq:答案+当前二进制位
    	scanf("%lld%lld",&n,&k);
    	for(int i=1;i<=n;i++) {scanf("%lld",&a[i]); sum[i]=sum[i-1]+a[i];}
    	int logn=log(sum[n])/log(2)+1;//最高二进制位
    	for(int p=logn;p>=0;p--)
    	{
    		memset(dp,0,sizeof(dp)); dp[0][0]=1;
    		qwq=ans+(1ll<<p);	
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=k;j++)
    				for(int l=1;l<=i;l++)
    					if((qwq&(sum[i]-sum[l-1]))==qwq && dp[l-1][j-1]) dp[i][j]=1;
    		ans+=dp[n][k]*(1ll<<p);
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    【bzoj2588】Count on a tree
    【bzoj4205】卡牌配对
    【bzoj1502】月下柠檬树
    【learning】快速沃尔什变换FWT
    【bzoj3672】购票
    bzoj1402:[HAOI2008]硬币购物
    bzoj1090:[SCOI2003]字符串折叠
    bzoj1260[CQOI2007]涂色paint
    2016.08.07计算几何总结测试day2
    2016.08.06计算几何总结测试day1
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14354585.html
Copyright © 2011-2022 走看看