dp4--codeVs1043 方格取数
dp4--codeVs1043 方格取数
一、心得
二、题目
三、分析
* codeVs1043方格取数.cpp
* 分析:
* 把这个问题看成两个人同时走就ok了
* 状态:
* f[h1][w1][h2][w2]表示第一个人走到(h1,w1)位置和第二个人走到(h2,w2)位置所取的最大和
* 最终状态:
* f[n][n][n][n]
* 初始状态:
* f[0][0][0][0] (都没走的情况,这就是最初的情况)
* 只可能两个人同时走了或者没走,不可能一个人走了,一个人没走
*
* 状态转移方程:
* 走到(h1,w1),(h2,w2)的四种方式:
* 1、都向下走 f[h1-1][w1][h2-1][w2]
* 2、都向右走 f[h1][w1-1][h2][w2-1]
* 3、第一个人向下,第二个人向右 f[h1-1][w1][h2][w2-1]
* 4、第一个人向右,第二个人向下 f[h1][w1-1][h2-1][w2]
* 用T表示这四种状态里面最优的一个
* T=max(f[h1-1][w1][h2-1][w2],f[h1][w1-1][h2][w2-1],f[h1-1][w1][h2][w2-1],f[h1][w1-1][h2-1][w2])
* 如果(h1,w1)==(h2,w2)
* f[h1][w1][h2][w2]=a[h1][w1]+T
* 如果(h1,w1)!=(h2,w2)
* f[h1][w1][h2][w2]=a[h1][w1]+a[h2][w2]+T
四、AC代码
5ms
1 /* 2 * codeVs1043方格取数.cpp 3 * 分析: 4 * 把这个问题看成两个人同时走就ok了 5 * 状态: 6 * f[h1][w1][h2][w2]表示第一个人走到(h1,w1)位置和第二个人走到(h2,w2)位置所取的最大和 7 * 最终状态: 8 * f[n][n][n][n] 9 * 初始状态: 10 * f[0][0][0][0] (都没走的情况,这就是最初的情况) 11 * 只可能两个人同时走了或者没走,不可能一个人走了,一个人没走 12 * 13 * 状态转移方程: 14 * 走到(h1,w1),(h2,w2)的四种方式: 15 * 1、都向下走 f[h1-1][w1][h2-1][w2] 16 * 2、都向右走 f[h1][w1-1][h2][w2-1] 17 * 3、第一个人向下,第二个人向右 f[h1-1][w1][h2][w2-1] 18 * 4、第一个人向右,第二个人向下 f[h1][w1-1][h2-1][w2] 19 * 用T表示这四种状态里面最优的一个 20 * T=max(f[h1-1][w1][h2-1][w2],f[h1][w1-1][h2][w2-1],f[h1-1][w1][h2][w2-1],f[h1][w1-1][h2-1][w2]) 21 * 如果(h1,w1)==(h2,w2) 22 * f[h1][w1][h2][w2]=a[h1][w1]+T 23 * 如果(h1,w1)!=(h2,w2) 24 * f[h1][w1][h2][w2]=a[h1][w1]+a[h2][w2]+T 25 * 26 */ 27 28 #include <iostream> 29 #include <cstdio> 30 #define maxn 13 31 using namespace std; 32 int n; 33 int f[maxn][maxn][maxn][maxn]; 34 int a[maxn][maxn]; 35 36 void initArr_a() { 37 for (int i = 1; i < maxn; i++) { 38 for (int j = 1; j < maxn; j++) { 39 a[i][j] = 0; 40 } 41 } 42 } 43 44 void readData() { 45 cin >> n; 46 int h, w, x; 47 while (scanf("%d %d %d", &h, &w, &x) == 3) { 48 bool t1 = h == 0 && w == 0 && x == 0; 49 if (t1) 50 break; 51 a[h][w] = x; 52 } 53 } 54 55 void printArr_a() { 56 for (int i = 1; i <= n; i++) { 57 for (int j = 1; j <= n; j++) { 58 printf("%5d", a[i][j]); 59 } 60 cout << endl; 61 } 62 } 63 64 void initArr_f() { 65 for (int i1 = 0; i1 <= n; i1++) { 66 for (int i2 = 0; i2 <= n; i2++) { 67 for (int i3 = 0; i3 <= n; i3++) { 68 for (int i4 = 0; i4 <= n; i4++) { 69 f[i1][i2][i3][i4] = 0; 70 } 71 } 72 } 73 } 74 //都没出发的情况 75 f[0][0][0][0] = 0; 76 77 } 78 void init() { 79 initArr_a(); 80 readData(); 81 //printArr_a(); 82 initArr_f(); 83 } 84 85 int max4(int a, int b, int c, int d) { 86 int tmp1 = max(a, b); 87 int tmp2 = max(c, d); 88 return max(tmp1, tmp2); 89 } 90 91 void dp() { 92 for (int i1 = 1; i1 <= n; i1++) { 93 for (int i2 = 1; i2 <= n; i2++) { 94 for (int i3 = 1; i3 <= n; i3++) { 95 for (int i4 = 1; i4 <= n; i4++) { 96 int tmp= max4(f[i1-1][i2][i3-1][i4],f[i1][i2-1][i3][i4-1],f[i1-1][i2][i3][i4-1],f[i1][i2-1][i3-1][i4]); 97 if(i1==i3&&i2==i4){ 98 f[i1][i2][i3][i4]=a[i1][i2]+tmp; 99 } 100 else{ 101 f[i1][i2][i3][i4]=a[i1][i2]+a[i3][i4]+tmp; 102 } 103 } 104 } 105 } 106 } 107 } 108 109 void printAns(){ 110 cout<<f[n][n][n][n]<<endl; 111 } 112 113 int main() { 114 //freopen("src/codeVs1043.txt", "r", stdin); 115 init(); 116 dp(); 117 printAns(); 118 return 0; 119 } 120 121 /* 122 * 注意点 123 * 1、在找初始状态上面还有点问题 124 * 一般是f[i][0],f[0][j],f[0][0],还有一些看题目 125 * 多维也是仿照两维来写状态转移方程 126 * 2、找准初始状态的实际意义,状态转移方程就好写了 127 * 3、向下和向右走正好对应x,y的++ 128 */
五、注意点
1、在找初始状态上面还有点问题 一般是f[i][0],f[0][j],f[0][0],还有一些看题目 多维也是仿照两维来写状态转移方程 2、找准初始状态的实际意义,状态转移方程就好写了 3、向下和向右走正好对应x,y的++
版权申明:欢迎转载,但请注明出处
一些博文中有一些参考内容因时间久远找不到来源了没有注明,如果侵权请联系我删除。
在校每年国奖、每年专业第一,加拿大留学,先后工作于华东师范大学和香港教育大学。
2024-10-30:27岁,宅加太忙,特此在网上找女朋友,坐标上海,非诚勿扰,vx:fan404006308
AI交流资料群:753014672