牛客小白月赛1 G あなたの蛙は旅⽴っています【图存储】【DP】

题目链接:https://www.nowcoder.com/acm/contest/85/G

思路:

 

DP 空间可以优化成一维的, 用一维数组的 0 号单元保存左斜对角的值即可。

存图这里真不好理解 = =

 

 AC 代码:

  1 #include <algorithm>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <map>
  7 #include <queue>
  8 #include <set>
  9 #include <vector>
 10 
 11 using namespace std;
 12 
 13 
 14 #define max3(x, y, z) max(max((x), (y)), (z))
 15 #define min3(x, y, z) min(mix((x), (y)), (z))
 16 #define pb push_back
 17 #define ppb pop_back
 18 #define mk make_pair
 19 
 20 #define debug_l(a) cout << #a << " " << (a) << endl
 21 #define debug_b(a) cout << #a << " " << (a) << " "
 22 #define testin(filename) freopen((filename) ,"r",stdin)
 23 #define testout(filename) freopen((filename) ,"w",stdout)
 24 
 25 typedef long long ll;
 26 typedef unsigned long long ull;
 27 
 28 
 29 const double PI  = 3.14159265358979323846264338327;
 30 const double E   = exp(1);
 31 const double eps = 1e-6;
 32 
 33 const int INF    = 0x3f3f3f3f;
 34 const int NINF   = 0xc0c0c0c0;
 35 const int maxn   = 3e3 + 5;
 36 const int MOD    = 1e9 + 7;
 37 
 38 
 39 int Map[maxn][maxn], Cur[maxn], dp[maxn][maxn];
 40 int main()
 41 {
 42     //testin("data1.in");
 43     int n;
 44     scanf("%d", &n);
 45     memset(Map, NINF, sizeof(Map));
 46     memset(Cur, 0, sizeof(Cur));
 47     memset(dp, 0, sizeof(dp));
 48     int vis = 1 + (4 * (n - 1));
 49     int cur = 2 * n - 1;
 50     int i, j;
 51 
 52     for (int i = 0; i < vis - n; i++) {
 53         if (i <= i % n)
 54             Cur[i] = i % n + 1;
 55         else {
 56             if (n & 1)
 57                 Cur[i] = (i & 1) ? n - 1 : n;
 58             else
 59                 Cur[i] = (i & 1) ? n : n - 1;
 60         }
 61     }
 62     for (int i = vis - 1; i >= vis - n; i--)
 63         Cur[i] = vis - i;
 64 
 65     vector <int> v[vis];
 66     int temp;
 67     for (i = 0; i < vis; i++)
 68     {
 69         for (j = 0; j < Cur[i]; j++)
 70         {
 71             scanf("%d", &temp);
 72             v[i].push_back(temp);
 73         }
 74     }
 75 
 76 
 77 
 78     int len = cur / 2 + 1;
 79     int flag = 0;
 80     for (i = 0, j = n; i < len; i++, j++)
 81     {
 82         for (int l = 0, k = flag; l < j; l++, k++)
 83         {
 84             Map[i][l] = v[k][v[k].size() - 1];
 85             v[k].pop_back();
 86             if (v[k].size() == 0)
 87                 flag++;
 88         }
 89     }
 90 
 91     for (j -= 2; i < cur; i++, j--)
 92     {
 93         for (int l = (cur - j), k = flag; l < cur; l++, k++)
 94         {
 95             Map[i][l] = v[k][v[k].size() - 1];
 96             v[k].pop_back();
 97             if (v[k].size() == 0)
 98                 flag++;
 99         }
100     }
101 
102     dp[0][0] = Map[0][0];
103     for (int i = 1; i < cur; i++) {
104         dp[0][i] = Map[0][i] + dp[0][i - 1];
105         dp[i][0] = Map[i][0] + dp[i - 1][0];
106     }
107 
108     for (int i = 1; i < cur; i++)
109         for (int j = 1; j < cur; j++)
110             dp[i][j] = Map[i][j] + max3(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]);
111 
112     cout << dp[cur - 1][cur - 1] << endl;
113     return 0;
114 }

 

 

参考原文:https://blog.csdn.net/Dup4plz/article/details/79639771

转载于:https://www.cnblogs.com/TianyuSu/p/9382779.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值