状态
d
p
[
i
]
[
j
]
:
前
i
列
,
选
取
最
大
值
状
态
为
j
的
最
大
值
dp[i][j]:前i列,选取最大值状态为j的最大值
dp[i][j]:前i列,选取最大值状态为j的最大值
#include<bits/stdc++.h>usingnamespace std;#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)#define _rev(i, a, b) for (int i = (a); i >= (b); --i)#define _for(i, a, b) for (int i = (a); i < (b); ++i)#define _rof(i, a, b) for (int i = (a); i > (b); --i)#define oo 0x3f3f3f3f#define ll long long#define db double#define eps 1e-8#define bin(x) cout << bitset<10>(x) << endl;#define what_is(x) cerr << #x << " is " << x << endl#define met(a, b) memset(a, b, sizeof(a))#define all(x) x.begin(), x.end()#define pii pair<int, int>intnxt(){int ret =0;scanf("%d",&ret);return ret;}signedmain(){int t =nxt();while(t--){int n =nxt(), m =nxt();
vector<vector<int>>dp(m +1, vector<int>(1<< n,0)),mat(n +1, vector<int>(m +1,0));_rep(i,1, n)_rep(j,1, m) mat[i][j]=nxt();_rep(i,1, m){_for(cur,0,1<< n){for(int sub = cur;; sub =(sub -1)& cur){int res =0, add = cur - sub;_rep(r,0, n -1){int val =0;_rep(j,0, n -1){if(add &(1<< j))
val += mat[(r + j)% n +1][i];}
res =max(res, val);}
dp[i][cur]=max(dp[i][cur], dp[i-1][sub]+ res);if(sub ==0)break;}}}
cout << dp[m][(1<< n)-1]<< endl;}}
hard-version数据范围:
n
≤
12
,
m
≤
2000
n \leq 12,m \leq 2000
n≤12,m≤2000
#include<bits/stdc++.h>usingnamespace std;#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)#define _rev(i, a, b) for (int i = (a); i >= (b); --i)#define _for(i, a, b) for (int i = (a); i < (b); ++i)#define _rof(i, a, b) for (int i = (a); i > (b); --i)#define oo 0x3f3f3f3f#define ll long long#define db double#define eps 1e-8#define bin(x) cout << bitset<10>(x) << endl;#define what_is(x) cerr << #x << " is " << x << endl#define met(a, b) memset(a, b, sizeof(a))#define all(x) x.begin(), x.end()#define pii pair<int, int>constint maxn =2e3+5;intnxt(){int ret =0;scanf("%d",&ret);return ret;}signedmain(){int t =nxt();while(t--){int n =nxt(), m =nxt(), cnt =0;
vector<vector<int>>dp(2, vector<int>(1<< n,0)),mat(n +1, vector<int>(m +1,0));
vector<pii>arr(m +1);_rep(i,0, m) arr[i].second = i;_rep(i,1, n){_rep(j,1, m){
mat[i][j]=nxt();
arr[j].first =max(arr[j].first, mat[i][j]);}}sort(arr.begin()+1, arr.end(),[](pii a, pii b){return a.first > b.first;});int q =min(m, n);
vector<vector<int>>pre(q +1, vector<int>(1<< n,0));_rep(i,1, q){int id = arr[i].second;_rep(cur,0,(1<< n)-1)//所有状态{int res =0;_for(s,0, n){//起点int val =0;_for(j,0, n){if(cur &(1<< j)){
val += mat[(s + j)% n +1][id];}}
res =max(res, val);}
pre[i][cur]=max(pre[i][cur], res);}}_rep(i,1,min(m, n)){_for(cur,0,1<< n){for(int sub = cur;; sub =(sub -1)& cur){int add = cur - sub;
dp[cnt][cur]=max(dp[cnt][cur], dp[cnt ^1][sub]+ pre[i][add]);if(sub ==0)break;}}
cnt ^=1;}
cout << dp[cnt ^1][(1<< n)-1]<< endl;}}