TJ
题目描述
有 \(n\) 道题需要按顺序验,验第 \(i\) 道题会让比赛的安全度增加 \(a_i\)。
由于时间紧迫,你决定只验其中 \(m\) 道题,跳过剩下的题。
当连续跳过若干道题时,前 \(k\) 道题每道会让安全度降低 \(b\),剩余每道会让安全度降低 \(c\)。
比如当 \(k=4\) 时,如果连续跳过 \(5\) 道题会让安全度降低 \(4\times b+ 1\times c\),如果连续跳过 \(2\) 道题会让安全度降低 \(2\times b\)。
求安全度的最大值是多少。
格式
输入格式
第一行包含两个整数 \(n,m\),分别表示题的总数量和你决定验的数量。
第二行包含 \(n\) 个整数 \(a_i\),分别表示验每道题使得安全度增加的值。
第三行包含三个整数 \(k,b,c\),表示连续跳过多道题时,前 \(k\) 道题每道会让安全度降低 \(b\),剩余每道会让安全度降低 \(c\)。
输出格式
输出一个整数表示安全度的最大值。
样例
样例输入 #1
8 2
1 3 2 1 6 4 1 1
1 1 100
样例输出 #1
-294
样例解释 #1
使得安全度的最大的其中一种验题方案为:验第 \(2,5\) 道题,总得分为 \((-1)+3+(-1)+(-100)+6+(-1)+(-100)+(-100)=-294\)。
数据规模
对于 \(20\%\) 的数据,\(n\leq 200\)。
另有 \(10\%\) 的数据,\(k=1\)。
另有 \(10\%\) 的数据,\(b=c\)。
对于 \(100\%\) 的数据,\(1\leq m\leq n\leq 6000\),\(1\leq a_i\leq 10^4\),\(1\leq k\leq n\),\(1\leq b\leq c\leq 10^4\)。
思路
\(dp_{i,j} 前j题已经验了i题的最大安全值,第j题要验\)。
分两类转移:设上次验题位置为 \(p-1\)。
- 上一次验题的位置距离此时不超过 \(k\),即\(j-p\),用单调队列维护 \(p\),\(dp_{i,j}=dp_{i-1,p-1}-b\times (j-p)=dp_{i-1,p}-b\times (j)+b\times p+a_j\),用单调队列维护 \(dp_{i-1,p}+ b\times (p+1))\) 其实是 \(b\times p\) 但是写 \(b\times (p+1)\) 更方便。
- 上一次验题的位置距离此时超过 \(k\),所以用
mx记录前缀的 \(dp_{i-1,j-k-1}+c\times (j-k)\) 。
第二步推导:
然后 mx 是个前缀,和上面那一段就是一样的了,将 mx 代入( mx 中的 \(j-k\) 为 \(p\))。
\(dp_{i,j}=dp_{i-1,p-1}-b\times k-c\times (j-p-k)+a_j\\=dp_{i-1,p-1}-b\times k-c\times j+c\times p+c\times k\\=dp_{i-1,p-1}+c \times p+c\times k-c\times j\\=mx+c\times k-c\times j\)。
代码
#include<bits/stdc++.h>
#define int long long
#define IN_ONLINE 0
using namespace std;
const string file="";
const int ralsei=0;
int n,m;
int dp[6010][6010];
int a[6010];
int k,b,c;
int calc(int l,int r)
{
return (r-l+1<=k?b*(r-l+1):b*k+c*(r-l+1-k));
}
signed main()
{
#if IN_ONLINE
freopen((file+".in").c_str(),"r",stdin);
freopen((file+".out").c_str(),"w",stdout);
#endif
ios::sync_with_stdio(ralsei);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
cin>>k>>b>>c;
int ans=INT_MIN;
memset(dp,-0x3f,sizeof(dp));
for(int i=1;i<=m;i++)
{
deque<int> q;
dp[i-1][ralsei]=ralsei;
int mx=INT_MIN;
for(int j=i;j<=n;j++)
{
/*第一种*/
while(!q.empty()&&dp[i-1][q.back()-1]+b*q.back()<=dp[i-1][j-1]+b*j)
{
q.pop_back();
}
q.push_back(j);
while(!q.empty()&&j-q.front()>k)
{
q.pop_front();
}
dp[i][j]=dp[i-1][q.front()-1]-calc(q.front(),j-1)+a[j];
/*第二种*/
dp[i][j]=max(dp[i][j],a[j]+mx-k*b-c*j+c*k);
if(j>=k+1)
{
mx=max(mx,dp[i-1][j-k-1]+c*(j-k));
}
if(i == m)
{
ans=max(ans,dp[i][j]-calc(j+1,n));
}
}
}
cout<<ans<<'\n';
return ralsei;
}

浙公网安备 33010602011771号