時間限制:c/c++ 1秒,其他語言2秒
空間限制:c/c++ 131072k,其他語言262144k
64bit io format: %lld
題目描述
現在給你n個正整數ai,每個數給出一「好數程度」 gi(數值相同但位置不同的數之間可能有不同的好數程度)。對於在 i 位置的數,如果有一在j位置的數滿足 j < i 且 ai=aj,則你可以將位於[i,j]閉區間內的序列評為「好序列」,然後獲得∑gk(j≤k≤i)(此閉區間內「好數程度」之和)分數。
注意: 在所有情況下,每個數都只能被乙個」好序列」包含(只能與其他相應數被評為」好序列」一次);在符合要求的情況下,」好序列」的評定次數不受限制,且通過不同」好序列」獲得的分數可以累加。
輸入描述:
第一行有乙個正整數n。
接下來的一行有n個正整數ai,表示意義如上。
(保證ai在32位整型範圍內)
接下來的一行有n個正整數gi,表示ai的」好數程度」。
(保證gi在64位整型範圍內)
輸出描述:
乙個整數,你可以獲得的最大分數(通過不同」好序列」獲得的分數可以累加),保證答案在64位整型範圍內。
示例1
輸入 複製
7 1 2 1 2 3 2 3
1 4 3 4 3 4 5
輸出 複製
23 備註:
資料範圍 2≤n≤300000
分析: 因為每個點只可以用一次,所以我們可以用多開乙個狀態看是否取得第i個點,即dp
[0][
i]d p[
0][i
]表示[1
−i[ 1−
i]區間的不取g[
i]g [i
]的最大值,dp
[1][
i]d p[
1][i
]表示[1
−i] [1−
i]
區間的取g[
i]g [i
]的最大值.
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int n = (int) 300000 + 11;
const int m = (int) 1e6 + 11;
const int mod = (int)1e9 + 7;
const int inf =(int)0x3f3f3f3f;
#include
using namespace __gnu_cxx;
ll a[n], g[n], dp[2][n]; //dp[0][i] 表示不取a[i]的最大值, dp[1][i] 表示取a[i]的最大值.
int main()
memset(dp, 0, sizeof(dp));
maplast;
for(int i = 1; i <= n; i++)
last[a[i]] = i;
}printf("%lld\n", max(dp[0][n], dp[1][n]));
return 0;
}
Wannafly挑戰賽21 C 大水題
題目描述 現在給你n個正整數ai,每個數給出一 好數程度 gi 數值相同但位置不同的數之間可能有不同的好數程度 對於在 i 位置的數,如果有一在j位置的數滿足 j i 且 ai aj,則你可以將位於 i,j 閉區間內的序列評為 好序列 然後獲得 gk j k i 此閉區間內 好數程度 之和 分數。注...
Wannafly挑戰賽21 C 大水題
題目描述 現在給你n個正整數ai,每個數給出一 好數程度 gi 數值相同但位置不同的數之間可能有不同的好數程度 對於在 i 位置的數,如果有一在j位置的數滿足 j i 且 ai aj,則你可以將位於 i,j 閉區間內的序列評為 好序列 然後獲得 gk j k i 此閉區間內 好數程度 之和 分數。注...
Wannafly挑戰賽A 概率DP
給你乙個長 n 的序列,m 次查詢 每次查詢給乙個 x,然後 從序列的最左端 1 開始,每次隨機的選擇乙個右端點 r,如果兩個端點間的區間和不超過 x 就進行一次分割,然後把左端點變成 r 1,否則一直隨機下去。問這樣分割出來的期望段數 第一行兩個數 n,m 之後一行 n 個數表示這個序列 之後m行...