题目链接:Vasya And The Mushrooms

题意

在一个 2×n2×n2\times n 的网格内,每一格都有一个蘑菇,第一行第 iii 格内的蘑菇每分钟长大 ai" role="presentation" style="position: relative;">aiaia_i,第二行第 iii 格内的蘑菇每分钟长大 bi" role="presentation" style="position: relative;">bibib_i,VasyaVasyaVasya 从第 111 行第 1" role="presentation" style="position: relative;">111 列的网格开始走起,每分钟都只能往相邻网格内移动,每一格蘑菇都必须经过一次(不能多于一次),最后不必回到初始位置,问如何规划路线才能使 VasyaVasyaVasya 收获的蘑菇最多。

输入

第一行包含一个整数 n (1≤n≤3×105)n(1≤n≤3×105)n~(1\leq n\leq3\times10^5),第二行为 nnn 个整数 a1,a2,⋯,an" role="presentation" style="position: relative;">a1,a2,⋯,ana1,a2,⋯,ana_1,a_2,\cdots,a_n,第三行为 nnn 个整数 b1,b2,⋯,bn " role="presentation" style="position: relative;">b1,b2,⋯,bn b1,b2,⋯,bn b_1,b_2,\cdots,b_n~,其中 1≤ai,bi≤106。1≤ai,bi≤106。1\leq a_i,b_i\leq10^6。

输出

输出最大能够收获的蘑菇数量。

样例

输入
3
1 2 3
6 5 4
输出
70
提示
最优的路线如下:

最后收获的蘑菇为:0⋅1+1⋅2+2⋅3+3⋅4+4⋅5+5⋅6=700·1+1·2+2·3+3·4+4·5+5·6=700·1+1·2+2·3+3·4+4·5+5·6=70
输入
3
1 1000 10000
10 100 100000
输出
543210
提示
最优的路线如下:

最后收获的蘑菇为:0⋅1+1⋅10+2⋅100+3⋅1000+4⋅10000+5⋅100000=5432100·1+1·10+2·100+3·1000+4·10000+5·100000=5432100·1+1·10+2·100+3·1000+4·10000+5·100000=543210

题解

由于每个网格都必须经过一次,所以从左上角开始的路线只有两类:“↓→↑→↓→↑→\downarrow\rightarrow\uparrow\rightarrow” 折返以及在某一次往右时停止折返,一直往右直到最后一格,然后返回,一般的情况如下(也可能在第二行一直往右,到最后从第一行返回):

因此就是枚举中断往返开始一直往右的点,取最大值,在枚举中间点的时候,每次都需要 O(1)O(1)O(1) 地求出贡献,首先用 dfsdfsdfs 预处理出 “↓→↑→↓→↑→\downarrow\rightarrow\uparrow\rightarrow” 走法的每个点的系数(从左上角点按照“下上右”的顺序 dfsdfsdfs 就可以得到):

然后从右往左递推一下后半段(先往右到最后,再往左回来的部分)的贡献,首先假设到某个点 iii 的时候的系数为 x" role="presentation" style="position: relative;">xxx,则后面接着所有点的系数为:

继续算从第 i−2i−2i-2 个点开始右转的贡献:

其中 x−4x−4x-4 为第 i−2i−2i-2 个点上面第二张系数图中对应的系数,对比上一张系数图可以发现,从第 iii 列到第 n" role="presentation" style="position: relative;">nnn 列所有的系数贡献都减 222,而从第 i−2" role="presentation" style="position: relative;">i−2i−2i-2 到第 i−1i−1i-1 列的贡献需要根据 iii 的位置进行计算,因此就可以从 n" role="presentation" style="position: relative;">nnn 到 111 递推得到从任何一列开始右转的贡献,最终 O(2n)" role="presentation" style="position: relative;">O(2n)O(2n)O(2n) 地枚举转折点取最大值就能得到答案。

过题代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;#define LL long long
const int maxn = 300000 + 100;
int n;
bool vis[2][maxn];
LL num[2][maxn], c[2][maxn], L[2][maxn], R[2][maxn];
LL sum[maxn];
const int dir[3][2] = {1, 0, -1, 0, 0, 1};bool in(int x, int y) {return x >= 0 && x < 2 && y >= 0 && y < n;
}void dfs(int x, int y, LL cc) {vis[x][y] = true;c[x][y] = cc;for(int i = 0; i < 3; ++i) {int xx = x + dir[i][0];int yy = y + dir[i][1];if(in(xx, yy) && !vis[xx][yy]) {L[xx][yy] = L[x][y] + cc * num[x][y];dfs(xx, yy, cc + 1);}}
}int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);#endif // Dmaxiyaios::sync_with_stdio(false);while(scanf("%d", &n) != EOF) {memset(sum, 0, sizeof(sum));for(int i = 0; i < 2; ++i) {for(int j = 0; j < n; ++j) {scanf("%I64d", &num[i][j]);sum[j] += num[i][j];vis[i][j] = false;R[i][j] = 0;}}for(int i = n - 2; i >= 0; --i) {sum[i] += sum[i + 1];}dfs(0, 0, 0);int Begin_up, Begin_down;if(n % 2 == 0) {Begin_up = n - 2;LL cc = c[0][n - 2];R[0][n - 2] = cc * num[0][n - 2] + (cc + 1) * num[0][n - 1] + (cc + 2) * num[1][n - 1] + (cc + 3) * num[1][n - 2];Begin_down = n - 1;cc = c[1][n - 1];R[1][n - 1] = cc * num[1][n - 1] + (cc + 1) * num[0][n - 1];} else {Begin_up = n - 1;LL cc = c[0][n - 1];R[0][n - 1] = cc * num[0][n - 1] + (cc + 1) * num[1][n - 1];Begin_down = n - 2;cc = c[1][n - 2];R[1][n - 2] = cc * num[1][n - 2] + (cc + 1) * num[1][n - 1] + (cc + 2) * num[0][n - 1] + (cc + 3) * num[0][n - 2];}for(int i = Begin_up; i - 2 >= 0; i -= 2) {LL cc = c[0][i - 2];R[0][i - 2] = R[0][i] - sum[i] * 2;R[0][i - 2] += cc * num[0][i - 2] + (cc + 1) * num[0][i - 1];cc += (n - i) * 2 + 2;R[0][i - 2] += cc * num[1][i - 1] + (cc + 1) * num[1][i - 2];}for(int i = Begin_down; i - 2 >= 0; i -= 2) {LL cc = c[1][i - 2];R[1][i - 2] = R[1][i] - sum[i] * 2;R[1][i - 2] += cc * num[1][i - 2] + (cc + 1) * num[1][i - 1];cc += (n - i) * 2 + 2;R[1][i - 2] += cc * num[0][i - 1] + (cc + 1) * num[0][i - 2];}LL aans = 0;for(int i = 0; i < 2; ++i) {for(int j = 0; j < n; ++j) {if((i + j) % 2 == 0) {aans = max(aans, L[i][j] + R[i][j]);}}}printf("%I64d\n", aans);}return 0;
}

Codeforces 1016C Vasya And The Mushrooms(动态规划)相关推荐

  1. codeforces 1016C - Vasya And The Mushrooms 【构造 + 思维】

    题目链接:戳这里 题意:从(1,1)出发,一遍把格子走完,每个格子只能走一次.问怎么走总和最大. 解题思路:画图可知,总共就3种走法的混合. dw: 样例1的走法 up: 样例1反过来的走法 lp: ...

  2. 1016C. Vasya And The Mushrooms

    可以知道有两种走法 一种是蛇形上下移动 另一种是直接移动到底再转回来 那么可以先处理三种走法(走到底的情况分为从上开始和从下开始)在每个点的值,再加起来找出最大值 很有趣的是:走到底的情况要走的相对顺 ...

  3. cf Educational Codeforces Round 48 C. Vasya And The Mushrooms

    原题: C. Vasya And The Mushrooms time limit per test2 seconds memory limit per test256 megabytes input ...

  4. CodeForces-1016C Vasya And The Mushrooms(模拟+思维+前缀和的前缀和) 解题报告 Apare_xzc

    CodeForces-1016C Vasya And The Mushrooms(模拟+思维+二重前缀和 ) 解题报告 xzc 2019/4/7 这周周赛的C题:wyt学姐的恶意   这道题周赛的时候 ...

  5. 51nod 1536不一样的猜数游戏 思路:O(n)素数筛选法。同Codeforces 576A Vasya and Petya‘s Game。

    废话不多说,先上题目. 51nod Codeforces 两个其实是一个意思,看51nod题目就讲的很清楚了,题意不再赘述. 直接讲我的分析过程:刚开始拿到手有点蒙蔽,看起来很难,然后......然后 ...

  6. Codeforces Beta Round #10 D. LCIS 动态规划

    D. LCIS 题目连接: http://www.codeforces.com/contest/10/problem/D Description This problem differs from o ...

  7. Codeforces 979E Kuro and Topological Parity - 动态规划 - 组合数学

    题目传送门 传送点 题目大意 给定$n$个标号依次为$1, 2, \cdots, n$的点,其中一些点被染成一些颜色,剩下的点没有染色.你需要添加一些有向边并将剩下的点染色,满足有向边从编号小的一端指 ...

  8. CF1016C Vasya And The Mushrooms 题解

    这道题一眼就是一个DP(大雾),但题目中有一句很有趣的话 "He wants to visit all the cells exactly once and maximize the tot ...

  9. CodeForces - 1036D Vasya and Arrays(思维)

    题目链接:点击查看 题目大意:先规定对数组的一种操作,是可以将相邻的一段数字合并成这段数字之和,然后给出两个数组,问若要将两个数组通过上述操作变得相等,那么经过操作后的数组最大长度是多少 题目分析:因 ...

  10. CodeForces - 1030C Vasya and Golden Ticket(思维)

    题目链接:点击查看 题目大意:给定长度为n的字符串,字符串全部由0~9的数字组成,要求将字符串划分为连续的子字符串,要求每个子字符串的和都要相等,问给定字符串能否成功划分 题目分析:简单思维,因为划分 ...

最新文章

  1. 求未知数X最临近的能被某个数字N整除的数
  2. python学习第四课
  3. 2021陇南高考成绩查询,2021年陇南中考成绩公布查询时间 陇南中考成绩查询方式入口...
  4. webstorm中git密码输入错误,重置问题
  5. 阿里云原生多模数据库Lindorm联合东软云科技,赋能车联网数字化运营运维创新升级
  6. window10系统 同时安装支持 jdk 1.7和1.8环境
  7. idea页面简单介绍
  8. matlab中服从高斯分布的矩阵_一些张量的计算步骤matlab代码
  9. HTML5 学习笔记
  10. idea messages中文乱码_2019.2版本IDEA控制台中文乱码尝试了很多方法都不行
  11. mysql强制指定索引_mysql强制索引和禁止某个索引
  12. vue项目没有router文件夹_Vue路由(vue-router)配置实战——动态路由,重定向,工程非根目录...
  13. 正确使用“下划线”一词
  14. 借助开源项目 学习软件开发
  15. java中随机字符串生成器_java随机字符串生成器
  16. Android 课程表
  17. 常见负载均衡服务器介绍
  18. js网页进度条等待特效
  19. WinMerge的使用(代码相同却提示有差异)。
  20. Yamaha DGX660 电钢琴aux-in只响一边的处理记录

热门文章

  1. Qt添加分割线(很简单的方法)
  2. ajax authorization,ajax跨域,_ajax Authorization 鉴权失败,ajax跨域 - phpStudy
  3. linux 目录历史于特点,linux 返回上次历史目录
  4. 第二课——如何有逼格地打字
  5. 计算机如何安装程序,如何手动安装计算机驱动程序
  6. web 页面实现页面右下角弹窗功能
  7. # 第一次面试问题详解
  8. Oracle数据库限制ip访问
  9. 天神娱乐实控人朱晔宣布离职:暂时的离开是为更好相见
  10. 电脑技巧:电脑内存不足怎么办?看完你就会了!