简单阅读程序
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int MAXN = 13;
int T, n, m;
struct Col {
int a[MAXN], maxx;
void Clear() {
maxx = 0;
}
void Intt() {
for (int i = 0; i < n; ++i)
maxx = max(maxx, a[i]);
}
bool operator < (const Col &col) const {
return maxx > col.maxx;
}
} c[114518];
int w[1 << MAXN], dp[MAXN][1 << MAXN];
void nxt(int &x, int y) {
x = (x - 1) & y;
}
signed main() {
scanf("%d%d", &n, &m);
memset(dp, 0, sizeof(dp));
for (int i = 0; i < m; ++i)
c[i].Clear();
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
cin >> c[j].a[i];
for (int j = 0; j < m; ++j)
c[j].Intt();
sort(c, c + m);
for (int i = 0; i < min(n, m); ++i) {
for (int j = 0; j < (1 << n); ++j) {
w[j] = 0;
for (int k = 0; k < n; ++k) {
int res = 0;
for (int l = 0; l < n; ++l)
if ((1 << l) & j)
res += c[i].a[(l + k) % n];
w[j] = max(w[j], res);
}
}
for (int j = 0; j < (1 << n); ++j) {
if (i == 0) {
dp[i][j] = w[j];
continue;
}
dp[i][j] = dp[i - 1][j];
int k = j;
while(k) {
dp[i][j] = max(dp[i][j], dp[i - 1][k] + w[k ^ j]);
nxt(k, j);
}
}
}
cout << dp[(n < m ? n : m) - 1][(1 << n) - 1] << endl;
return 0;
}
时间限制 \(8s\) 空间限制 \(1G\)
输入 \(n,m\),\(n\leq 12, m\leq 2000\) 表示一个 \(n\times m\) 的矩阵,提示:进行一些操作,最后求出行里最大值的和。然后输入这个矩阵,保证矩阵中每一个数 \(a_{i,j}\),满足 \(a_{i,j} \leq {10}^5\)。
判断题:
- (2') 若将 nxt 函数替换成下面的函数,程序会出错。
void nxt(int &x, int y) {
x = x - 1 & y;
}
-
(1.5') 若将
dp[(n < m ? n : m) - 1][(1 << n) - 1]
替换成为dp[n < m ? n : m - 1][(1 << n) - 1]
程序会出错。 -
(1.5') 如果此题将 \(m\) 范围扩大成为 \(114514\) 此程序将无法正确通过此题。
-
(2') 本题所支持的操作是交换两个行。
-
(2') 程序只会选择列里最大的前 \(n\) 列。
选择题:
- (2') 这题用了什么算法
A.状压 dp B. 数位 dp C.猴王算法 D. ssh 算法
- (4') 程序的时间复杂度为
A. \(n^32^n+n3^n+m\log m\) B. \(n^32^n+n^23^n+nm\log m\) C. \(n^2m2^n+n3^n+m\log m\) D.\(n^32^n+n^23^n+m\log n\)
- (4')如果输入数据如下,输出为
3 6
4 1 5 2 10 4
8 6 6 4 9 10
5 4 9 5 8 7
A. 25 B. 27 C. 29 D. 33
- (10') €€£是什么