《是男人就下100层》 | ||||||
| ||||||
Description | ||||||
王金刚在玩一个《是男人就下100层》的游戏 这个游戏是这样的 第一层有一块浮板 第二层有二块浮板 ... 第n层有n块浮板 当玩家在第i块浮板上 下一次他只能到达下一层的第i-1块(如果有的话) 或者 第i块或者第i+1块浮板 (类似金字塔形状) 王金刚正在第一层 王金刚想要从第一层走到最底下一层 每一块浮板上都有一个积分 王金刚想获得的积分最大 当然事情没有这么简单 我们会给出几块必须要路过的浮板 请你输出王金刚走到所有必须路过的浮板并且到达最底层的最多得分 | ||||||
Input | ||||||
第一行输入T表示T组输入 T<=500 每组样例如下 | ||||||
Output | ||||||
输出走到所有必须路过的浮板并且到达最底层 如果不能达成请输出-1 (行末带有换行) | ||||||
Sample Input | ||||||
3 10 5 1 4 5 7 8 6 3 5 2 4 2 5 6 3 7 5 6 3 7 8 5 1 2 3 5 8 6 4 4 8 9 6 5 8 9 6 1 2 5 9 8 9 9 9 1 1 3 4 5 6 7 8 1 5 2 1 1 2 1 4 3 6 4 7 3 10 4 1 4 5 7 8 6 3 5 2 4 2 5 6 3 7 5 6 3 7 8 5 1 2 3 5 8 6 4 4 8 9 6 5 8 9 6 1 2 5 9 8 9 9 9 1 1 3 4 5 6 7 8 1 5 2 2 1 2 1 7 5 2 1 10 0 1 4 5 7 8 6 3 5 2 4 2 5 6 3 7 5 6 3 7 8 5 1 2 3 5 8 6 4 4 8 9 6 5 8 9 6 1 2 5 9 8 9 9 9 1 1 3 4 5 6 7 8 1 5 2 | ||||||
Sample Output | ||||||
55 64 65 | ||||||
Source | ||||||
20231126 |
由于数据量很小 只限制了1<=n<=10 0<=m<=10 所以可以使用dfs来解决 但是聪明的你并不打算这么做 想用更短的时间来解决问题 万一后台不小心(故意的还是不小心的)扩大了数据范围呢 所以这道题就可以使用dp来做了
现在给出一个简化版本:
有一个三角形,从数组(1,1)的位置出发(初始索引为1,1),向下一行走,只能走到正下方或者右下方的位置,如果走到了该位置,那么你会获得等于该数字大小的分数(初始分数为(1,1)位置的数字的大小),直到走到最后一层,找出你可以获得最大的分数并输出。
输入:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
30
输出:
30
Hint:7->3->8->7->5==30
这是一道很简单的dp题目 需要考虑最初的状态 也就是dp[1][1] = a[1][1];,转移也不难想到dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + a[i][j]; 那么代码就很好写出来了
/*
* @author: LANSGANBS
* @Date: Created - 2023-12-04 14:00:26
* 写完这道就去原
*/
#include <bits/stdc++.h>
#define endl '\n'
#define buff ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
/*
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize(3)
*/
using namespace std;
#define ll long long
#define int ll
const int N = 1e3 + 7;
int a[N][N];
int dp[N][N];
int best_score = -1;
void solve()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cin >> a[i][j];
}
}
dp[1][1] = a[1][1];
for (int i = 2; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + a[i][j];
}
}
for (int i = 1; i <= n; i++)
{
best_score = max(best_score, dp[n][i]);
}
cout << best_score << endl;
// wout <<L" "<<endl;
// cout << R"( )" << endl;
}
signed main()
{
// setlocale(LC_ALL, "");
buff;
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
/*
* @LastEditTime:2023-12-04 14:10:18
*/
这道题弄懂之后 那么最初的问题也就很好想出了 最初的问题不过是可以向左下方走 而且多了几个必须走的位置
/*
* @author: LANSGANBS
* @Date: Created - 2023-12-04 13:59:30
* 写完这道就去原
*/
#include <bits/stdc++.h>
#define endl '\n'
#define buff ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
/*
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize(3)
*/
using namespace std;
#define ll long long
#define int ll
int T;
int n, m;
int arr[15][15];
int must_arrive[15];
void solve()
{
cin >> T;
while (T--)
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cin >> arr[i][j];
}
must_arrive[i] = -1;
}
int mark = 0;
for (int i = 1; i <= m; i++)
{
int k, v;
cin >> k >> v;
if (must_arrive[k] != -1 && must_arrive[k] != v)
{
mark = 1;
}
must_arrive[k] = v;
}
if (mark == 1)
{
cout << -1 << endl;
continue;
}
long long dp[15][15] = {0};
for (int i = 1; i <= n; i++)
{
if (must_arrive[n] == -1 || must_arrive[n] == i)
{
dp[n][i] = arr[n][i];
}
else
{
dp[n][i] = -1;
}
dp[i][0] = -1;
dp[i][i + 1] = -1;
}
for (int row = n - 1; row >= 1; row--)
{
for (int col = 1; col <= row; col++)
{
if (must_arrive[row] == -1 || must_arrive[row] == col)
{
int best_score = -1;
for (int i = -1; i <= 1; i++)
{
if (dp[row + 1][col + i] > best_score)
{
best_score = dp[row + 1][col + i];
}
}
if (best_score == -1)
{
dp[row][col] = -1;
}
else
{
dp[row][col] = best_score + arr[row][col];
}
}
else
{
dp[row][col] = -1;
}
}
}
cout << dp[1][1] << endl;
}
// wout <<L" "<<endl;
// cout << R"( )" << endl;
}
signed main()
{
// setlocale(LC_ALL, "");
buff;
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
return 0;
}
/*
* @LastEditTime: 2023-12-04 14:51:59
*/