9268. 酒鬼(DP)

OpenJudge 9268:酒鬼

  • 题目
  • 思路
    • 代码

题目传送门

题目

Santo刚刚与房东打赌赢得了一间在New Clondike 的大客厅。今天,他来到这个大客厅欣赏他的奖品。房东摆出了一行瓶子在酒吧上。瓶子里都装有不同体积的酒。令Santo高兴的是,瓶子中的酒都有不同的味道。房东说道:“你可以喝尽可能多的酒,但是一旦打开酒盖你就必须把它喝完,喝完一瓶后把它放回原处。还有一件最重要的事,你必须从左至右依次喝,并且不能连续超过三瓶,不然会给你带来坏运气。”现在可怜的Santo站在酒吧前努力的想着,他到底应该喝哪几瓶才能使喝的酒最多呢?请帮助他找出他应该喝的酒瓶号,因为思考让他感到不安。

输入格式

第一行一个整数 N ,有 N 个酒瓶。接下有 N 行,第 i+1 行的数字代表酒瓶 i 中酒的体积。

输出格式

一个数字,喝的酒的最大总体积。遵守以上规则,使得三个连续瓶子中至少一个瓶子是满的。

数据范围

N < = 700 N<=700 N<=700

输入输出样例

样例输入1

6
6
10
13
9
8
1

样例输出1

33

思路

DP。题目大概意思就是,一共有N个酒瓶,每个酒瓶最多只能选一次,每次喝酒最多喝 2 次,在连续喝酒次数 < = 2 <= 2 <=2 的条件下可以喝的酒的最大总体积。
9268. 酒鬼(DP)_第1张图片

dp[i]考虑前 i 个酒瓶喝的酒的最大总体积。
dp[i][0/1/2]考虑前 i 个酒瓶且第 i 个酒瓶是连续喝酒次数中第0 / 1 / 2 次喝,喝的酒的最大总体积。(连续第0次喝,即没有喝第 i 个酒瓶)。
dp[i] [1]= dp[i - 1][0]+b_i;
如果第 i 瓶酒是连续喝酒的第 1 次喝酒,即第 i - 1个酒瓶没有被喝。那么就在第 i - 1瓶没有喝的酒的最大总体积的基础上,加上第 i 个酒瓶中酒的体积,就是第 i 瓶酒是在连续喝酒次数的第 1 次喝酒的情况下,喝的酒的最大总体积。
dp[i] [2]= dp[i - 1][1]+b_i;
边界条件:
dp[1][0]表示前 1 个酒瓶(第 1 个酒瓶)且第 1 个酒瓶没有被喝过,喝的酒的最大总体积,即啥也没喝的时候。
dp[1][1]表示前 1 个酒瓶(第 1 个酒瓶)且第 1 个酒瓶是第 1 次被喝,喝的酒的最大总体积,即刚喝了 1 瓶的时候。

下面这个题和该题的思路几乎一样,有兴趣可以看一下。
LeetCode 198.打家劫舍

代码

#include
#include
using namespace std;
const int N = 710;
int n , ans, dp[N][2], b[N];
int main() {
     
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) scanf("%d", &b[i]);
    dp[1][0] = 0;
    dp[1][1] = b[1];
	for(int i = 1; i <= n; i++) {
     
		dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][1], dp[i - 1][2]));
		dp[i][1] = dp[i - 1][0] + b[i];
		dp[i][2] = dp[i - 1][1] + b[i];
	} 
	ans = max(dp[n][0], max(dp[n][1], dp[n][2]));
	printf("%d", ans);
	return 0;
}

时间复杂度: O ( n ) O(n) O(n)

你可能感兴趣的:(DP,动态规划)