D:
看样例+分析得知,假设现在要选(i)个,那么能达到的最大的值就是(sum_{i_1}=sum^{n}_{x=n-i+1}{x}), 最小值就是(sum_{i_2}=sum^{i-1}_{x=0}{x}),那么每次可选择的数量就是(sum_1-sum_2+1),那么答案就为(sum_{i=k}^{n+1}({sum_{i_1}-sum_{i_2} + 1}))
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
const LL MOD = 1e9+7;
void run_case() {
int n, k;
cin >> n >> k;
LL ans = 0;
for(int i = k; i <= n+1; ++i) {
LL t1 = 1LL*(i-1)*i/2;
LL t2 = 1LL*(n+n-i+1)*i/2;
(ans += t2 - t1 + 1) %= MOD;
}
cout << ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}
E:
一开始用贪心做,将(A_i)从大到小排序,每次都放在端点,但是样例2、3单纯用该策略是不行的,样例3中,若选用贪心策略,得:
(111556),但是使得最大值的方法为: (611155), 第二种方法时(6)就不是最优,所以应该根据数据范围想到该题为DP问题,但是放的策略肯定也是放在两端为最优,那么可以放在某个区间的两端,可以联想到区间dp
设(dp_{i,j})为闭区间([i,j])还未被选择时,已经选择的最优答案,得到状态转移:
(dp_{i,j} = max(dp_{i,j+1}+A_k*|j+1-pos_k|, dp_{i-1, j}+A_k*|i-1-pos_k|), k = n-(j-i+1)),(k)表示当前选择是第几个
最终答案就是(max(dp_{i,i-1}), iin [1, n])
#include<bits/stdc++.h>
using namespace std;
#define ms(x,y) memset(x, y, sizeof(x))
#define lowbit(x) ((x)&(-x))
#define sqr(x) ((x)*(x))
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
void run_case() {
int n; cin >> n;
vector<pll> a;
for(int i = 1; i <= n; ++i) {
LL t; cin >> t;
a.emplace_back(t, 1LL*i);
}
sort(a.begin(), a.end(), [&](pll a, pll b) {
return a.first > b.first;
});
vector<vector<LL>> dp(n+2, vector<LL>(n+2));
for(int i = 1; i <= n; ++i) {
for(int j = 0; j <= i; ++j) { // len = r - l + 1, len = n - i
int l = j+1, r = n - i + l - 1;
if(r+1<=n) dp[l][r] = max(dp[l][r], dp[l][r+1]+abs(r+1-a[i-1].second)*a[i-1].first);
if(l-1>=1) dp[l][r] = max(dp[l][r], dp[l-1][r]+abs(l-1-a[i-1].second)*a[i-1].first);
}
}
LL ans = 0;
for(int i = 1; i <= n; ++i) ans = max(ans, dp[i][i-1]);
cout << ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0);
cout.flags(ios::fixed);cout.precision(9);
//int t; cin >> t;
//while(t--)
run_case();
cout.flush();
return 0;
}
F:
我先放个坑在这里