CF1209E2 Rotate Columns (hard version)
题意:
分析:
首先我们看看数据范围: 各种怪解时间复杂度较大的解法去做。
先不考虑
设
那么我们可以枚举当前列所选行的状态
设
则显然有:
val 很容易在
但是递推的过程时间复杂度高达
所以我们考虑优化。
这里有一个贪心:
当
所以此时
代码:
#include<bits/stdc++.h> using namespace std; const int N=13,M=2000+10; int a[N][M],n,m; int maxcol[M],rk[M]; int f[N][(1<<N)+10],val[N][(1<<N)+10],tmp[N*2]; void init(){ memset(maxcol,0,sizeof maxcol); memset(f,0,sizeof f); memset(val,0,sizeof val); for(int i=1;i<=m;i++)rk[i]=i; return; } bool cmp(int x,int y){ return maxcol[x]>maxcol[y]; } signed main(){ std::ios::sync_with_stdio(false); cin.tie(0);cout.tie(0); int T;cin>>T; while(T--){ cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ cin>>a[i][j]; } } init(); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ maxcol[j]=max(maxcol[j],a[i][j]); } } sort(rk+1,rk+m+1,cmp); m=min(n,m); for(int id=1;id<=m;id++){ int i=rk[id]; //cout<<i<<" "; for(int j=1;j<=n;j++){ tmp[j]=tmp[j+n]=a[j][i]; } for(int s=0;s<(1<<n);s++){ for(int j=1;j<=n;j++){ int cnt=0; for(int k=1;k<=n;k++){ if((1<<k-1)&s){ cnt+=tmp[k+j-1]; //cout<<id<<" "<<s<<" "<<tmp[k+j-1]<<endl; } } val[id][s]=max(val[id][s],cnt); } //cout<<id<<" "<<s<<" "<<val[id][s]<<endl; } } for(int i=1;i<=m;i++){ for(int s=0;s<(1<<n);s++){ //cout<<f[i][s]<<endl; f[i][s]=f[i-1][s]; for(int s0=s;s0;s0=(s0-1)&s){ f[i][s]=max(f[i][s],f[i-1][s^s0]+val[i][s0]); } } } cout<<f[m][(1<<n)-1]<<"\n"; } return 0; } /* 1 3 3 9 9 9 1 1 1 1 1 1 */
本文作者:Little_corn
本文链接:https://www.cnblogs.com/little-corn/p/18157448
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步