对于 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; }