↓ Skip to main content
  1. Posts/

codeforces 855 B. Marvolo Gaunt's Ring (前缀最大,dp)

·531 words·2 mins
Note: This article is available in Chinese only. 本文暂无英文版本。 View original

题目链接

题意:给出n,p,q,r,以及n(1E5)个数,所有数的范围都是[-1E9,1E9],现在问p_a[i]+q_a[j]+r*a[k]的最大值,满足1<=i<=j<=k<=n

思路:傻逼dp…

我。。好菜啊。。。万年dp苦手。

直接转载官方题解了。。。思路的重点是维护了一个最大前缀值。

dp[i][0] stores maximum of value p·a__x for x between 1 and i. Similarly dp[i][1] stores the maximum value of p·a__x + q·a__y such that x ≤ y ≤ i and dp[i][2] stores maximum value of p·a__x + q·a__y + r·a__z for x ≤ y ≤ z ≤ i.

To calculate the dp:

dp[i][0] = max(dp[i - 1][0], p·a__i)

dp[i][1] = max(dp[i - 1][1], dp[i][0] + q·a__i)

dp[i][2] = max(dp[i - 1][2], dp[i][1] + r·a__i)

The answer will be stored in dp[n][2]

代码实现
 1/* ***********************************************
 2Author :111qqz
 3Created Time :2017年09月25日 星期一 19时26分34秒
 4File Name :B.cpp
 5************************************************ */
 6
 7#include <cstdio>
 8#include <cstring>
 9#include <iostream>
10#include <algorithm>
11#include <vector>
12#include <queue>
13#include <set>
14#include <map>
15#include <string>
16#include <cmath>
17#include <cstdlib>
18#include <ctime>
19#define PB push_back
20#define fst first
21#define sec second
22#define lson l,m,rt<<1
23#define rson m+1,r,rt<<1|1
24#define ms(a,x) memset(a,x,sizeof(a))
25typedef long long LL;
26#define pi pair < int ,int >
27#define MP make_pair
28
29using namespace std;
30const double eps = 1E-8;
31const int dx4[4]={1,0,0,-1};
32const int dy4[4]={0,-1,1,0};
33const int inf = 0x3f3f3f3f;
34const int N=1E5+7;
35LL a[N];
36LL p,q,r;
37int n;
38LL dp[N][3];
39int main()
40{
41#ifndef  ONLINE_JUDGE
42    freopen("./in.txt","r",stdin);
43#endif
44    cin>>n>>p>>q>>r;
45    for ( int i = 1 ; i <= n ; i++) cin>>a[i];
46    LL ans = 1LL<<60;
47    ans*=-5LL;
48    ms(dp,0xc0);
49    //重要的是维护一个前缀最大值。
50    for ( int i = 1 ; i <= n ; i++)
51    dp[i][0] = max(dp[i-1][0],p*a[i]);
52    for ( int i = 1 ; i <= n ; i++)
53    dp[i][1] = max(dp[i-1][1],dp[i][0]+q*a[i]);
54    for ( int i = 1 ; i <= n ; i++)
55    dp[i][2] = max(dp[i-1][2],dp[i][1]+r*a[i]);
56    cout<<dp[n][2]<<endl;
57
58#ifndef ONLINE_JUDGE
59    fclose(stdin);
60#endif
61    return 0;
62}

Related

leetcode 152. Maximum Product Subarray (最大连续子序列乘积,dp)

·289 words·1 min
Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4], the contiguous subarray [2,3] has the largest product = 6. 思路:由于有正,有负,还有0.。。所以比最大子串之和要复杂一些。。。 dp[i].max表示到当前位置的最大乘积。

leetocde 63. Unique Paths II

·337 words·1 min
Follow up for “Unique Paths”: Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. For example, There is one obstacle in the middle of a 3x3 grid as illustrated below. 1[ 2 [0,0,0], 3 [0,1,0], 4 [0,0,0] 5] The total number of unique paths is 2. 题意:从左上到右下的方案数,有些点不能走。

leetcode 64. Minimum Path Sum (二维dp)

·371 words·1 min
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. 数字三角形。。。。从左上到右下问最短路径。。每次只能向下或者向右。。。 wa了一次。。。是因为边界值赋值成了0.。。求最短路径显然因为赋值成inf才对orz..果然傻了。。

BZOJ 2748: [HAOI2012]音量调节 (dp)

·820 words·2 mins
2748: [HAOI2012]音量调节 # Time Limit: 3 Sec Memory Limit: 128 MB Submit: 1814 Solved: 1148 [Submit][Status][Discuss] Description # 一个吉他手准备参加一场演出。他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都要改变一次音量。在演出开始之前,他已经做好了一个列表,里面写着在每首歌开始之前他想要改变的音量是多少。每一次改变音量,他可以选择调高也可以调低。 音量用一个整数描述。输入文件中给定整数beginLevel,代表吉他刚开始的音量,以及整数maxLevel,代表吉他的最大音量。音量不能小于0也不能大于maxLevel。输入文件中还给定了n个整数c1,c2,c3…..cn,表示在第i首歌开始之前吉他手想要改变的音量是多少。 吉他手想以最大的音量演奏最后一首歌,你的任务是找到这个最大音量是多少。

BZOJ 1207: [HNOI2004]打鼹鼠 (LIS)

·965 words·2 mins
1207: [HNOI2004]打鼹鼠 # Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2854 Solved: 1390 [Submit][Status][Discuss] Description # 鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的。根据这个特点阿Q编写了一个打鼹鼠的游戏:在一个nn的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气。你可以控制一个机器人来打鼹鼠,如果i时刻鼹鼠在某个网格中出现,而机器人也处于同一网格的话,那么这个鼹鼠就会被机器人打死。而机器人每一时刻只能够移动一格或停留在原地不动。机器人的移动是指从当前所处的网格移向相邻的网格,即从坐标为(i,j)的网格移向(i-1, j),(i+1, j),(i,j-1),(i,j+1)四个网格,机器人不能走出整个nn的网格。游戏开始时,你可以自由选定机器人的初始位置。现在你知道在一段时间内,鼹鼠出现的时间和地点,希望你编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。