T1227泥棒ああフー
41.31%1000ms 65536K
タイトル説明
ああフーは経験豊富な強盗です。暗くて強風を利用して、AhFuは今夜ストリートショップを略奪するつもりです。
この通り、合計のN
店、各店はいくらかの現金を持っています。アフの以前の調査では、隣接する2つの店舗を同時に略奪した場合にのみ、街頭警報システムが作動し、警察が群がることを知りました。
犯罪を犯すことに常に用心深い泥棒として、AhFuは盗むために警察に追い詰められる危険を冒すことを望んでいません。彼は警察に警告せずに今夜どれだけの現金を手に入れることができるか知りたいですか?
入力フォーマット
入力の最初の行は整数T(T≤50)であり、合計でTグループのデータがあることを示します。
次のデータセットごとに、最初の行は整数N(1≤N≤100,000)であり、合計でN個のストアがあることを示します。
2行目は、スペースで区切られたN個の正の整数で、各店舗の現金の金額を示しています。各店舗の現金の額は1,000を超えません。
出力フォーマット
データのセットごとに、1行を出力します。
この行には、AhFuが警察に警告せずに取得できる現金の金額を表す整数が含まれています。
促す
最初の例では、Ah Fuは2番目のショップをショップリフトに選び、得られた現金の額は8でした。2番目の例では、Ah Fuが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;
}