计蒜客 T1227 大盗阿福(动态规划入门 C++)

T1227 大盗阿福

41.31% 1000ms 65536K

题目描述

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。

这条街上一共有 N 家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。

作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?

输入格式

输入的第一行是一个整数 T(T≤50) ,表示一共有 T 组数据。

接下来的每组数据,第一行是一个整数 N (1≤N≤100,000),表示一共有 N 家店铺。

第二行是 N 个被空格分开的正整数,表示每一家店铺中的现金数量。每家店铺中的现金数量均不超过 1000。

输出格式

对于每组数据,输出一行。

该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。

提示

对于第一组样例,阿福选择第 2 家店铺行窃,获得的现金数量为 8。对于第二组样例,阿福选择第 1 和 4 家店铺行窃,获得的现金数量为 10 + 14 = 24。

样例输入

2
3
1 8 2
4
10 7 6 14

样例输出

8
24

问题分析

opt[i]:到下标为i的最佳方案
由于样例输入太短,不方便分析,所以,重新写一个数组 m[] = {1,2,4,1,7,8,3}

在这里插入图片描述
我的分析有些简单,有不明白的大家可以去b站看博主 正月点灯笼 的 ‘动态规划(第2讲)’视频。

代码

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

#define N 100000
int m[N];	//存放每家店铺的现金金额 

int dp_maxM(int m[], int n){
    
    
	int dp_opt[n];	//存放最优子解 
	int A,B,res;	//A,B分别接收两种不同情况的结果,res为最后的解 
	
	//初始化 
	dp_opt[0] = m[0];
	dp_opt[1] = max(m[0],m[1]);
	res = m[0];
	 
	for(int i=2; i<n; i++){
    
    	//寻找最优子解 
		A = dp_opt[i-2] + m[i];
		B = dp_opt[i-1];
		dp_opt[i] = max(A, B);
	}
	
	for(int i=1; i<n; i++){
    
    	//在最优子解中找到最优解 
		if(res < dp_opt[i])
			res = dp_opt[i];
	}
	return res;
}

int main(){
    
    
	int T,n;
	cin >> T;
	for(int i=0; i<T; i++){
    
    
		cin >> n;
		for(int j=0; j<n; j++){
    
    
			cin >> m[j];
		}
		cout << dp_maxM(m,n) << endl;
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_44524918/article/details/108984737