正题
题目链接:https://cometoj.com/contest/58/problem/C?problem_id=2760
题目大意
若干个数对(ai,bi)(a_i,b_i)(ai,bi),总价值为
∑i=1n−1bi∗ai+1\sum_{i=1}^{n-1}b_i*a_{i+1}i=1∑n−1bi∗ai+1
然后可以选择一段区间的二元组将(ai,bi)(a_i,b_i)(ai,bi)变为(ai∗k,bi∗k)(a_i*k,b_i*k)(ai∗k,bi∗k)。
求最大价值
解题思路
考虑dpdpdp。
用fi,0/1/2f_{i,0/1/2}fi,0/1/2表示到了第iii个位置,还为选择,正在选择,已经选择完了
然后有动态转移方程
fi,0=fi−1,0+ai∗bi−1f_{i,0}=f_{i-1,0}+a_{i}*b_{i-1}fi,0=fi−1,0+ai∗bi−1
fi,1=max{fi−1,1+ai∗bi−1∗k∗k,fi−1,0+ai∗bi−1∗k}f_{i,1}=max\{f_{i-1,1}+a_i*b_{i-1}*k*k,f_{i-1,0}+a_i*b_{i-1}*k\}fi,1=max{fi−1,1+ai∗bi−1∗k∗k,fi−1,0+ai∗bi−1∗k}
fi,2=max{fi−1,1+ai∗bi−1∗k,fi−1,2+ai∗bi−1}f_{i,2}=max\{f_{i-1,1}+a_i*b_{i-1}*k,f_{i-1,2}+a_i*b_i-1\}fi,2=max{fi−1,1+ai∗bi−1∗k,fi−1,2+ai∗bi−1}
然后ans=max{fn,0,fn,1,fn,2}ans=max\{f_{n,0},f_{n,1},f_{n,2}\}ans=max{fn,0,fn,1,fn,2}
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+100;
ll n,k,a[N],b[N],f[N][3];
int main()
{scanf("%lld%lld",&n,&k);memset(f,127,sizeof(f));f[0][0]=0;for(ll i=1;i<=n;i++){scanf("%lld%lld",&a[i],&b[i]);f[i][0]=f[i-1][0]+a[i]*b[i-1];f[i][1]=min(f[i-1][0]+a[i]*b[i-1]*k,f[i-1][1]+a[i]*b[i-1]*k*k);f[i][2]=min(f[i-1][2]+a[i]*b[i-1],f[i-1][1]+a[i]*b[i-1]*k);}printf("%lld",min(f[n][2],min(f[n][1],f[n][0])));
}