标签:ems problem star tar cin algo ble out 循环
二维基础DP,每个 \(f[i,j]\) 都是从 \(f[i-1,j-1]\) 和 \(f[i-1,j]\) 转移过来,取 \(max\) ,最后循环最下层,取 \(max\) 即为答案
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 510;
int g[N][N];
int dp[N][N];
int INF = 1e9;
int main()
{
int n;
cin >> n;
for(int i = 1 ; i <= n ; i++)
for(int j = 1; j <= i ; j++)
cin >> g[i][j];
for (int i = 0; i <= n; i ++ )
for (int j = 0; j <= i + 1; j ++ )
dp[i][j] = -INF; //初始化所有值,防止边界情况出现问题
dp[1][1] = g[1][1];
for(int i = 2; i <= n ; i++)
for(int j = 1 ; j <= i ; j++)
dp[i][j] = g[i][j] + max(dp[i-1][j-1],dp[i-1][j]);
int ans = -INF;
for(int i = 1; i <= n ; i++)
ans = max(ans,dp[n][i]);
cout << ans << endl;
return 0;
}
二维基础DP,每个 \(f[i,j]\) 都是从 \(f[i-1,j]\) 和 \(f[i,j-1]\) 转移过来,取 \(max\) ,最后输出 \(f[n,m]\) 即可
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n,m;
int w[N][N];
int f[N][N];
int main()
{
int T;
cin >> T;
while(T--)
{
cin >> n >> m;
for(int i = 1; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
cin >> w[i][j];
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= m ; j++)
f[i][j] = max(f[i-1][j],f[i][j-1]) + w[i][j];
cout << f[n][m] << endl;
}
}
与摘花生相同,只需要分析出 \(2n-1\) 的意思是不走回头路,然后将摘花生的 \(max\) 改为 \(min\) 即可,但因为求最小值需要注意边界值的特殊情况
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int g[N][N];
int dp[N][N] = {0};
int main()
{
int n;
cin >> n;
memset(dp,0x3f,sizeof dp);
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= n ; j++)
cin >> g[i][j];
for(int i = 1 ; i <= n ; i++)
for(int j = 1 ; j <= n ; j++)
if(i==1 && j==1) dp[i][j] = g[i][j];
else dp[i][j] = min(dp[i-1][j],dp[i][j-1]) + g[i][j];
cout << dp[n][n];
}
与摘花生类似,但是需要本题为走两次, \(f[i_1,j_1,i_2,j_2]\) 表示所有从 \((1,1),(1,1)\) 分别走到 \((i_1,j_1),(i_2,j_2)\) 的路径的最大值
需要考虑 —— 如何处理 “同一个各自不能被重复选择”
进一步思考得出:只有在 \(i_1+j_1 == i_2 + j_2\) 时,两条路径的格子才可能重合
那么就可以优化成 \(f[k,i_1,i_2]\) 分别表示从 \((1,1),(1,1)\) 分别走到 \((i_1,k-i_1),(i_2,k-i_2)\) 的路径的最大值, \(k\) 表示当前走到坐标的横纵坐标之和
\(f[k][i_1][i_2]\) 作为最后一步时,两条线路分别有4种可能 —— 下下,下右,右下,右右 就分别对应 \(f[k-1][i1-1][i2-1]\) , \(f[k-1][i1-1][i2]\) , \(f[k-1][i1][i2-1]\) , \(f[k-1][i1][i2]\)
取 \(max\) 即可得出本题答案
#include<bits/stdc++.h>
using namespace std;
const int N = 15;
int n;
int w[N][N];
int f[N*2][N][N];
int main()
{
cin >> n;
int a,b,c;
while(cin >> a >> b >> c, a || b ||c) w[a][b] = c;
for(int k = 2; k <= n + n ; k++)
for(int i1 = 1 ; i1 <= n ; i1++)
for(int i2 = 1 ; i2 <= n ; i2++)
{
int j1 = k - i1, j2 = k - i2;
if(j1 >= 1 && j1 <= n && j2 >= 1 && j2 <= n)
{
int t = w[i1][j1];
if(i1 != i2) t += w[i2][j2];
int &x = f[k][i1][i2];
x = max(x,f[k-1][i1-1][i2-1] + t);
x = max(x,f[k-1][i1-1][i2] + t);
x = max(x,f[k-1][i1][i2-1] + t);
x = max(x,f[k-1][i1][i2] + t);
}
}
cout << f[n+n][n][n] << endl;
}
标签:ems problem star tar cin algo ble out 循环
原文地址:https://www.cnblogs.com/ieeeev/p/14532274.html