對於 100%100\%100% 的數據,1≤n≤106,1≤k≤106,1≤vi≤1091\leq n\leq 10^6,1\leq k\leq 10^6,1\leq v_i\leq 10^91≤n≤10隊列
6,1≤k≤106,1≤vi≤109。遊戲
題意 :相似於「拉火車」遊戲,不過不太同樣的是當出現相同的狀況後你能夠選擇拉或者不拉,ip
思路分析 : 一看就是個 dp ,
dp[i] = dp[i-1]
dp[i] = max(dp[i], dp[j-1]+sum[i]-sum[j-1]) , i 與 j 爲花色相同的地方
第一次寫的時候就相似純暴力的了,每次轉移的時候從前面全部相同的地方轉移,用 vector 存的,超時.... 後面發現 轉移方程中的式子是能夠優化的,每次找 dp[j-1]-sum[j-1]中最大的轉移便可
代碼示例 :
#define ll long long const ll maxn = 1e6+5; ll n, k; ll c[maxn], v[maxn]; ll sum[maxn], dp[maxn]; ll color[maxn]; void solve() { memset(color, 0x8f, sizeof(color)); for(ll i = 1; i <= n; i++){ dp[i] = dp[i-1]; dp[i] = max(dp[i], sum[i]+color[c[i]]); color[c[i]] = max(color[c[i]], dp[i-1]-sum[i-1]); } printf("%lld\n", dp[n]); } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n >> k; for(ll i = 1; i <= n; i++) { scanf("%lld", &c[i]); } for(ll i = 1; i <= n; i++) { scanf("%lld", &v[i]); sum[i] = sum[i-1]+v[i]; } solve(); return 0; }