題目描述
現在給你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
區間dp,但是常規區間dp方程式是列舉所有子區間
for (int len = 1; len < n; len++)
}}
dp[i]=max(dp[j-1]+sum(j~i))a[j]==a[i];
會超時,記錄相同數字的最優點
詳細看**:
#include#include#includeconst int maxn=300000+10;
typedef long long ll;
using namespace std;
mapp;
int a[maxn],best[maxn],last[maxn];
ll dp[maxn],sum[maxn];
int main()else }
int lin;
for(int i=1;i<=n;i++)
ll ans=0;
for(int i=1;i<=n;i++) //比如資料裡有3個2,就會比較前面那個2好一點,等到下次再遇到2時,再比較,但是
//每次只用比較前面那個2和最好的那個2就行
} ans=max(ans,dp[i]);
} printf("%lld\n",ans);
return 0;
}
Wannafly挑戰賽21 C 大水題
題目描述 現在給你n個正整數ai,每個數給出一 好數程度 gi 數值相同但位置不同的數之間可能有不同的好數程度 對於在 i 位置的數,如果有一在j位置的數滿足 j i 且 ai aj,則你可以將位於 i,j 閉區間內的序列評為 好序列 然後獲得 gk j k i 此閉區間內 好數程度 之和 分數。注...
Wannafly挑戰賽21 大水題 DP
時間限制 c c 1秒,其他語言2秒 空間限制 c c 131072k,其他語言262144k 64bit io format lld 題目描述 現在給你n個正整數ai,每個數給出一 好數程度 gi 數值相同但位置不同的數之間可能有不同的好數程度 對於在 i 位置的數,如果有一在j位置的數滿足 j ...
Wannafly挑戰賽A 概率DP
給你乙個長 n 的序列,m 次查詢 每次查詢給乙個 x,然後 從序列的最左端 1 開始,每次隨機的選擇乙個右端點 r,如果兩個端點間的區間和不超過 x 就進行一次分割,然後把左端點變成 r 1,否則一直隨機下去。問這樣分割出來的期望段數 第一行兩個數 n,m 之後一行 n 個數表示這個序列 之後m行...