Codeforces Round #584 E2. Rotate Columns (hard version)(状压DP)

https://codeforces.com/contest/1209/problem/E2

题意:

给定一个N×M 的矩阵,你可以对每一列的数字进行任意次的旋转操作(即整体向上或者整体向下)。输出在做出任意次旋转操作后每一行的最大值之和。


解题思路:看到n的范围很小,可以联想到状压DP来解,设dp【i】为状态i的最大值,所谓状态i,就是在i的二进制下,某位置为1则表示该行已找到最大值,为0则没有找到最大值,那么可以进行子集DP了。还有值得注意的是,我们最少可以在min(n,m)列中找打答案,所以先按每列的最大值排序,取前min(n,m)列就好了。

#include
using namespace std;
const int maxn=2e3+5;
int dp[1<<12];
int f[1<<12];
int f1[1<<12];
struct st{
	int id,w;
	bool operator < (const st & tem)const{
		return w>tem.w;
	}
}stm[maxn];
int a[15][maxn];
int use[maxn];
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=0;i 
 

  

你可能感兴趣的:(Codeforces Round #584 E2. Rotate Columns (hard version)(状压DP))