NC15335. Get the Highest Score
描述
For arbitrary i ∈ [1, m − 1], if it satisfies that vi ≠ vi+1, we think this compression method is “complete compression”. Otherwise, we think this compression method is “incomplete compression”.
There is an example of “complete compression”:
[10,10,4,4] ⇒ (2,10),(1,4),(1,4)
Today, Jelly gets an array A of length N. Jelly will execute the following three steps in order: Firstly, he can replace some (or all of) “−1” in the array to arbitrary integer he wants. Secondly, he can choose an arbitrary compression method to compress the array.
Thirdly, he will calculate the score of this compression method.
Jelly wants to know the highest score that he can get. Jelly is too busy, so he wants you for help.
输入描述
The first line contains an integer T, where T is the number of test cases. T test cases follow.For each test case, the first line contains one integer N, where N is the length of the array A.The second line contains N integers A1, A2, ... , AN.• 1 ≤ T ≤ 105.
• 1 ≤ N ≤ 105.
• −1≤Ai ≤106.
• the sum of N in all test cases doesn’t exceed 106.
输出描述
For each test case, print one line containing “Case #x: y”, where x is the test case number (starting from
1) and y is the highest score that Jelly can get.
示例1
输入:
2 9 0 1 1 0 0 -1 1 1 1 3 1 -1 -1
输出:
Case #1: 25 Case #2: 9
C++14(g++5.4) 解法, 执行用时: 473ms, 内存消耗: 2656K, 提交时间: 2018-12-07 01:22:23
#include <iostream> #include <vector> using namespace std; typedef long long ll; int main() { int Test; cin >> Test; for (int test = 1; test <= Test; ++test) { int n; cin >> n; vector<int> a(n + 1, -2); for (int i = 1; i <= n; ++i) { cin >> a[i]; } vector<ll> dp(n + 1, 0); int curIndex = 0; ll curLen = 0; ll prevLen = 0; for (int i = 1; i <= n; ++i) { if (a[i] == -1) ++curLen; else { if (a[i] != a[curIndex]) { curIndex = i; prevLen = curLen; } curLen = 0; } if (curIndex == 0) dp[i] = curLen * curLen; else { ll len = i - curIndex + 1; ll t1 = dp[curIndex - 1] + len * len; ll t2 = dp[curIndex - prevLen - 1] + (len + prevLen) * (len + prevLen); dp[i] = max(t1, t2); } } cout << "Case #" << test << ": " << dp[n] << endl; } return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 199ms, 内存消耗: 2020K, 提交时间: 2020-03-29 12:15:13
#include<stdio.h> #include<string.h> typedef long long ll; int n; int a[100001]; ll dp[100001]; int main() { int Test; scanf("%d",&Test); for(int test=1;test<=Test;++test) { scanf("%d",&n); a[0]=-2; for(int i=1;i<=n;++i) { scanf("%d",&a[i]); } int curIndex=0; ll curLen=0; ll prevLen=0; dp[0]=0; for(int i=1;i<=n;++i) { if(a[i]==-1) ++curLen; else { if(a[i]!=a[curIndex]) { curIndex=i; prevLen=curLen; } curLen=0; } if(curIndex==0) dp[i]=curLen*curLen; else { ll len=i-curIndex+1; ll t1=dp[curIndex-1]+len*len; ll t2=dp[curIndex-prevLen-1]+(len+prevLen)*(len+prevLen); dp[i]=t1>t2?t1:t2; } } printf("Case #%d: %lld\n",test,dp[n]); } return 0; }