[NOIP模拟] 矩阵
来源:互联网 发布:js elementHTML 编辑:程序博客网 时间:2024/06/15 20:41
Description
在给出的矩阵中,选出 k 个* * * * 的矩阵,求最* *。
Input
矩阵的信息 + k, 与模样。
Output
答案。
Solution :
这是一道 DP 题,本来在考场上,我是没有想出一个比较好的 DP 的,但是由于从最大 m 子段和,得到了启示,当然这道题可以花式 DP, 你
这里先说一下我的 DP, 记
首先我们先看一看DP[i][k][3] 是怎么转移的 :
1.与 i - 1 行的合并起来,能够合并的情况只有当i - 1行也是 3 的连通情况一种:
2.i行是独立成一个矩阵是,可以有前面的所有的k - 1情况更新过来 :
接下来是DP[i][k][2]的转移 :
1.可以由k - 2的所有状态转移 :
2.可以由k - 1的连通情况为 0, 1, 2 的状态转移 :
3.可以由 k 个矩阵 2 状态转移:
然后是DP[i][k][1]的转移 :
1.可以由所有的k - 1的状态转移 :
2.可以由 k 个矩阵的 1 的连通情况转移过来 :
接下来是要讲DP[i][k][0],但是这类的情况与上个状态是相似的,所以这里我就列方程:
好了这就是所有的转移,至于如何优化到
至于大佬的做法是多定了一维,表示不选这样就不用记录最大值直接
Code:
我的,希望你们喜欢。。。。。
#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <algorithm>#include <iostream>#include <cmath>#include <ctime>#include <map>#include <vector>using namespace std;inline int read() { int i = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) { if(ch == '-') f = -1; ch = getchar(); } while(isdigit(ch)) { i = (i << 3) + (i << 1) + ch - '0'; ch = getchar(); } return i * f;}const int MAXN = 100 + 5;int f[MAXN][15], dp[MAXN][15][4], a[MAXN], b[MAXN][2], pre[MAXN][2];inline int get(int i, int k) { return max(dp[i][k][0], max(dp[i][k][1], max(dp[i][k][2], dp[i][k][3])));}inline int get1(int i, int k) { return max(dp[i][k][0], max(dp[i][k][1], dp[i][k][3]));}inline int get2(int i, int k) { return max(dp[i][k][0], max(dp[i][k][1], dp[i][k][2]));}int main() { freopen("matrix.in", "r", stdin); //freopen("matrix.out", "w", stdout); int n = read(), m = read(), K = read(); if(m == 1) { for(int i = 1; i <= n; ++i) a[i] = read(); for(int k = 1; k <= K; ++k) { for(int i = 1; i <= n; ++i) { f[i][k] = -0x3f3f3f3f; if(i >= k) { f[i][k] = max(f[i][k], f[i - 1][k] + a[i]); for(int j = 1; j <= i - 1; ++j) f[i][k] = max(f[i][k], f[j][k - 1] + a[i]); } } } int ans = -0x3f3f3f3f; for(int i = K; i <= n; ++i) ans = max(ans, f[i][K]); printf("%d\n", ans); } else { for(int i = 1; i <= n; ++i) for(int j = 0; j < m; ++j) b[i][j] = read(); for(int i = 1; i <= n; ++i) for(int j = 0; j < m; ++j) pre[i][j] = pre[i - 1][j] + b[i][j]; for(int k = 1; k <= K; ++k) for(int i = 1; i <= n; ++i) { dp[i][k][0] = dp[i][k][1] = dp[i][k][2] = dp[i][k][3] = -0x3f3f3f3f;//3状态是并在一起 if(i * 2 >= k) { dp[i][k][3] = max(dp[i][k][3], get(i - 1, k - 1) + b[i][0] + b[i][1]); dp[i][k][3] = max(dp[i][k][3], dp[i - 1][k][3] + b[i][0] + b[i][1]); if(k >= 2) { dp[i][k][2] = max(dp[i][k][2], get(i - 1, k - 2) + b[i][0] + b[i][1]); dp[i][k][2] = max(dp[i][k][2], dp[i - 1][k][2] + b[i][0] + b[i][1]); dp[i][k][2] = max(dp[i][k][2], get2(i - 1, k - 1) + b[i][0] + b[i][1]); } for(int j = 1; j <= i - 2; ++j) { dp[i][k][3] = max(dp[i][k][3], get(j, k - 1) + b[i][0] + b[i][1]); dp[i][k][2] = max(dp[i][k][2], get(j, k - 2) + b[i][0] + b[i][1]); } } if(i * 2 - 1 >= k) { dp[i][k][0] = max(dp[i][k][0], dp[i - 1][k][0] + b[i][0]); dp[i][k][1] = max(dp[i][k][1], dp[i - 1][k][1] + b[i][1]); dp[i][k][0] = max(dp[i][k][0], dp[i - 1][k][2] + b[i][0]); dp[i][k][1] = max(dp[i][k][1], dp[i - 1][k][2] + b[i][1]); for(int j = 1; j <= i - 1; ++j) { dp[i][k][0] = max(dp[i][k][0], get(j, k - 1) + b[i][0]); dp[i][k][1] = max(dp[i][k][1], get(j, k - 1) + b[i][1]); int now1 = -0x3f3f3f3f, now2 = -0x3f3f3f3f; /*for(int l = j - 1; l <= i - 1; ++l) now1 = max(now1, pre[i][0] - pre[l][0]), now2 = max(now2, pre[i][1] - pre[l][1]); //cout<<now1<<' '<<now2<<'\n'; dp[i][k][0] = max(dp[i][k][0], dp[j][k - 1][1] + now1); dp[i][k][1] = max(dp[i][k][1], dp[j][k - 1][0] + now2);*/ } } } int ans = -0x3f3f3f3f; for(int i = 1; i <= n; ++i) ans = max(ans, get(i, K));//printf("%d %d %d %d\n", dp[i][2][0], dp[i][2][1], dp[i][2][2], dp[i][2][3]); printf("%d\n", ans); }}
Hart’s code
#include <cstdio>#include <cstring>inline int getch() { static int size = 0, pt = 0; static char buf[1048576]; if((size == pt) && (pt = buf[size = fread(buf, sizeof(char), 1048575, stdin)] = '\0', size == 0)) return EOF; return buf[pt++];}inline int get_int() { register int ch, flag = 1, x; for(ch = getch(); (unsigned)(ch ^'0') > 9; ch = getch()) if(ch == '-') flag = -1; if(ch == EOF) return EOF; for(x = ch ^ '0', ch = getch(); (unsigned)(ch ^ '0') < 10; ch = getch()) x = (x << 3) + (x << 1) + (ch ^ '0'); return x * flag;}struct IN { const IN& operator >> (char &ch) const { return ch = getch(), *this; } const IN& operator >> (int &x) const { return x = get_int(), *this; }} in;const int INF = 0x7F7F7F7F, NINF = 0x80808080;int N, M, K, A[105][2], DP[101][11][5], MaxDP[101][11];inline void init() { N = get_int(); M = get_int(); K = get_int(); for(register int i = 1; i <= N; ++i) for(register int j = 0; j < M; ++j) { A[i][j] = get_int(); }}inline int Max(register int a, register int b) { return a < b ? b : a; }inline void solve1() { for(register int i = 1; i <= N; ++i) for(register int j = 0; j <= K; ++j) { DP[i][j][0] = MaxDP[i - 1][j]; DP[i][j][1] = Max(DP[i - 1][j][1], (j ? MaxDP[i - 1][j - 1] : NINF)); if(DP[i][j][1] != NINF) DP[i][j][1] += A[i][0]; MaxDP[i][j] = Max(DP[i][j][0], DP[i][j][1]); } printf("%d\n", MaxDP[N][K]);}inline void solve() { memset(DP[0], 0x80, sizeof(DP[0])); memset(MaxDP[0], 0x80, sizeof(MaxDP[0])); DP[0][0][0] = MaxDP[0][0] = 0; if(M == 1) return solve1(); for(register int i = 1; i <= N; ++i) for(register int j = 0; j <= K; ++j) { DP[i][j][0] = MaxDP[i - 1][j]; DP[i][j][1] = Max( Max(DP[i - 1][j][1], DP[i - 1][j][3]), (j ? MaxDP[i - 1][j - 1] : NINF)); if(DP[i][j][1] != NINF) DP[i][j][1] += A[i][0]; DP[i][j][2] = Max( Max(DP[i - 1][j][2], DP[i - 1][j][3]), (j ? MaxDP[i - 1][j - 1] : NINF)); if(DP[i][j][2] != NINF) DP[i][j][2] += A[i][1]; DP[i][j][3] = Max( DP[i - 1][j][3], Max( (j ? Max(DP[i - 1][j - 1][1], DP[i - 1][j - 1][2]) : NINF), (j > 1 ? MaxDP[i - 1][j - 2] : NINF))); if(DP[i][j][3] != NINF) DP[i][j][3] += A[i][0] + A[i][1]; DP[i][j][4] = Max( DP[i - 1][j][4], (j ? MaxDP[i - 1][j - 1] : NINF)); if(DP[i][j][4] != NINF) DP[i][j][4] += A[i][0] + A[i][1]; MaxDP[i][j] = Max(Max(DP[i][j][0], DP[i][j][1]), Max( Max(DP[i][j][2], DP[i][j][3]), DP[i][j][4])); } printf("%d\n", MaxDP[N][K]);}int main() { init(); solve(); return 0;}
阅读全文
0 0
- 【NOIP模拟】矩阵
- [NOIP模拟] 矩阵
- NOIP模拟 Matrix 矩阵运算
- 【Noip模拟】【dp】【LIS】【矩阵快速幂】
- NOIP模拟题 [线段树][矩阵快速幂]
- Noip模拟
- NOIP模拟(10.20)T2 矩阵(bzoj1084 最大子矩阵)
- 【NOIP模拟】20151004模拟
- 【NOIP模拟】 20151005模拟
- 【NOIP模拟】 20151006模拟
- 【NOIP模拟】 20151007模拟
- 【NOIP模拟】20151014模拟
- 【NOIP模拟】20151015模拟
- MZ test17# NOIP模拟题 # T4 第4题 路线统计(route.cpp/pas)[key:矩阵]
- [NOIP模拟题][LIS][同余最短路][DP][矩阵快速幂][容斥原理]
- [NOIP模拟][LIS][数列映射][最短路][数论+图论][矩阵乘法][容斥原理]
- (noip 模拟 Matrix)<逃避矩阵乘法的好方法#滑稽>
- 【NOIP提高组】矩阵
- 关于maven报错:Plugin org.apache.maven.plugin:m(click for 2 more)
- [龙果学院] Spring Boot 教程笔记
- [LeetCode]27. Remove Element
- C++ Primer Plus第五版 第六章 编程练习答案
- C#语言和SQL Server数据库技术_用SQL语句操作数据
- [NOIP模拟] 矩阵
- Discrete-time LTI system : the convolution sum representation
- Canny边缘检测算法原理及其VC实现详解
- 洛谷P1364 医院设置
- 从地址空间看进程和线程
- Hibernate4 和 Hibernate5 创建session的区别
- Qt5 xml转Json
- 生活小记29
- 【日常】sublime text 3配置chrome插件LiveReload