(DP 遞推)2487 小b和環

2021-09-23 07:56:00 字數 1793 閱讀 4414

2 秒262,144 kb

20 分

3 級題

小b有乙個長度為n的環,每個點上有個數字。

現在請你選出一些點,滿足選出的任意兩個點在環上不相鄰,且選出的點的數字之和最大,你只需輸出這個最大值。

收起

第一行輸入乙個數n,其中0<n≤50000;

第二行輸入n個非負整數,第i個數表示環上順時針第i個點上的數字,以空格隔開。

0<=每個點上的數字<=10000。

輸出乙個數,表示最大值。
4

1 2 3 1

4
題解:剛開始我是這麼想的,dp[i] = max(dp[i-2] , dp[i-3]) + a[i] ,前 i 位 的值由前 i-2 或 前 i-3 遞推而來,最基本的遞推方程已經確立了;隨後交了一發,只過了一半。

wa :一維的dp只能維護 1 -  n 之間的不是相鄰的,不能保證 1 和 n 是否相鄰。

隨後我又想了想,選了n就不能選1,只能再開一維陣列標記前邊是否將起始點 1 包含了進去。

#include#include#include#include#include#include#include#include#include#include#include#include#include#define eps (1e-8)

#define max 0x3f3f3f3f

#define u_max 1844674407370955161

#define l_max 9223372036854775807

#define i_max 2147483647

#define re register

#define nth(k,n) nth_element(a,a+k,a+n); // 將 第k大的放在k位

#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 約瑟夫

#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,離散化

using namespace std;

inline int read()

while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();

return x * f;

}typedef long long ll;

const double pi = atan(1.)*4.;

const int m=1e3+5;

const int n=5e4+5;

// dp[i][0] 前 i 位不包含第一位的最大值

// dp[i][1] 前 i 位包含第一位的最大值

ll dp[n][2],a[n];

int main()

memset(dp,0,sizeof(dp));

dp[0][0]=0; dp[1][1]=a[1];

dp[2][0]=a[2]; dp[3][1]=dp[1][1]+a[3]; dp[3][0]=a[3];

for(int i=4;idp[n][0]=max(dp[n-2][0],dp[n-3][0])+a[n]; // 第 n 位只能取 0(0 代表不包含第一位

ll ans=0;

for(int i=1;i<=n;i++)

printf("%lld\n",ans);

return 0;

}

每日演算法 計數DP和遞推DP

計數pd就是emm感覺求那種什麼路徑和的就是計數那一類的,再概括一下就是可以不用其他操作直接將它相鄰或者說符合要求的 求和,就是下乙個位置的值。回到這題 用動規很好做。我們想要知道 0,0 到終點的位置的路徑,只需要知道終點已左終點已下的路徑為多少就行了。dp i j 0,0 到 i,j 位置的路徑...

(思維)2476 小b和序列

2 秒262,144 kb 20 分 3 級題 小b有乙個長度為n的序列a,她想求maxi你能幫幫她嗎?樣例解釋 選擇a2a2和a9a9,答案為min 8,7 9 2 49min 8,7 9 2 49,不存在其他選法答案更大,因此最大值就是49。收起第一行乙個數n,0 n 50000 第二行n個數表...

DP 小a和uim之大逃離

題目描述 瞬間,地面上出現了乙個n m的巨幅矩陣,矩陣的每個格仔上有一坨0 k不等量的魔液。怪物各給了小a和uim乙個魔瓶,說道,你們可以從矩陣的任乙個格仔開始,每次向右或向下走一步,從任乙個格仔結束。開始時小a用魔瓶吸收地面上的魔液,下一步由uim吸收,如此交替下去,並且要求最後一步必須由uim吸...