4418. 選元素
阿新 • • 發佈:2022-05-08
題目連結
4418. 選元素
給定一個長度為 \(n\) 的整數序列 \(a_1,a_2,…,a_n\)。
請你從中挑選 \(x\) 個元素,要求:
- 原序列中的每一個長度為 \(k\) 的連續子序列都至少包含一個被選中的元素。
- 滿足條件 \(1\) 的前提下,所選 \(x\) 個元素的相加之和應儘可能大。
輸出最大可能和。
輸入格式
第一行包含三個整數 \(n,k,x\)。
第二行包含 \(n\) 個整數 \(a_1,a_2,…,a_n\)。
輸出格式
如果無法滿足題目要求,則輸出 \(−1\)。
否則,輸出一個整數,表示所選元素的最大可能和。
資料範圍
前三個測試點滿足 \(1≤k,x≤n≤6\)
所有測試點滿足 \(1≤k,x≤n≤200,1≤a_i≤10^9\)。
輸入樣例1:
5 2 3
5 1 3 10 1
輸出樣例1:
18
輸入樣例2:
6 1 5
10 30 30 70 10 10
輸出樣例2:
-1
輸入樣例3:
4 3 1
1 100 1 1
輸出樣例3:
100
解題思路
dp
-
狀態表示:\(f[i][j]\) 表示前 \(i\) 個數且選了第 \(i\) 個數,共選了 \(j\) 個數的最大和
-
狀態計算:\(f[i][j]=max({f[t][j-1]})\),其中 \(i-t\leq k\)
-
時間複雜度:\(O(n^3)\)
程式碼
// Problem: 選元素 // Contest: AcWing // URL: https://www.acwing.com/problem/content/4421/ // Memory Limit: 256 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=205; int n,k,x; int a[N]; LL f[N][N]; int main() { help; cin>>n>>k>>x; for(int i=1;i<=n;i++)cin>>a[i]; memset(f,-0x3f,sizeof f); f[0][0]=0; for(int i=1;i<=n;i++) for(int j=1;j<=x;j++) for(int t=max(0,i-k);t<i;t++) f[i][j]=max(f[i][j],f[t][j-1]+a[i]); LL res=-1; for(int i=n;i>=n-k;i--) if(n-i+1<=k)res=max(res,f[i][x]); cout<<res; return 0; }