标签:scan 提示 两种 ali bsp cout 最大 while ring
阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。
这条街上一共有 N 家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。
作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?
输入的第一行是一个整数T(T≤50),表示一共有T组数据。
接下来的每组数据,第一行是一个整数N(1≤N≤100,000) ,表示一共有N家店铺。第二行是N个被空格分开的正整数,表示每一家店铺中的现金数量。每家店铺中的现金数量均不超过1000。
对于每组数据,输出一行。该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。
2 3 1 8 2 4 10 7 6 14
8 24
对于第一组样例,阿福选择第2家店铺行窃,获得的现金数量为8。
对于第二组样例,阿福选择第1和4家店铺行窃,获得的现金数量为10+14=24。
一道典型的动规题目。先设置状态。设数组value [i] 表示第 i 家店铺的现金数量,dp [i] [0/1] 表示第 i 家店铺的状态,0表示不洗劫这家店铺所能获得的最多现金,1表示洗劫这家店铺所能获得的最多现金。
两种情况:1.第 i 家店铺已经被洗劫了。那么与它相邻的第 i - 1 家店铺不能被洗劫,要不然就会触发警报。所以第 i 家店铺没有被洗劫的状态 dp [i] [0] 继承的是它前面一家店铺被洗劫的状态,同时还要加上洗劫第 i 家店铺获得的现金,也就是 dp [i] [1] = dp [i-1] [0] + value [i] ;
2.第 i 家店铺没有被洗劫。那么第 i - 1 家店铺有可能被洗劫也有可能没有,也就是说 dp [i] [0] 继承的是它的前面的店铺没有被洗劫和有被洗劫的状态,两者取一个最大值即可,即 dp [i] [0] = max ( dp [i-1] [0] , dp [i-1] [1] )。
至于初始状态,那就是 dp [1] [0] = 0 (很明显第一家店铺没有被洗劫,没有获得现金)和 dp [1] [1] = value [1](第一家店铺被洗劫,获得对应现金) 了。
同时要注意数据范围,不能太小,value 至少要开到大于 100,000 。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int dp[100001][2]; int value[100001]; int n,t;//店铺量,数据组数 int main() { scanf("%d",&t); while(t--) { n=read(); for(int i=1; i<=n; i++) { scanf("%d",&value[i]); } dp[1][0]=0; dp[1][1]=value[1]; for(int i=2; i<=n; i++) { dp[i][0]=max(dp[i-1][0],dp[i-1][1]); dp[i][1]=dp[i-1][0]+value[i]; } cout<<max(dp[n][0],dp[n][1])<<endl; memset(dp,0,sizeof(dp));//下一组数据 } return 0; }
标签:scan 提示 两种 ali bsp cout 最大 while ring
原文地址:https://www.cnblogs.com/jiangyuechen/p/12943658.html