题目链接
题解
emmmm,dp转移前缀和的构造方法不是和上一个题是一模一样的吗
不对,这不就是和上一个题一样吗,只是转移方程把i换成了x[i]....
详见bzoj3437: 小P的牧场
瞎jb写写就过了 tut
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
#define int long long
const int maxn = 1000007;
int a[maxn],b[maxn],q[maxn];
int n,dp[maxn];
int sum[maxn],cost[maxn];
//dp[i] = min{dp[j]+(sum[i]-sum[j])*x[i]-(cost[i]-cost[j])} +a[i]
double slop(int k,int j) {
return double (dp[j] - dp[k] + cost[j] - cost[k]) / double (sum[j] - sum[k]);
}
main() {
n = read();
for(int i = 1;i <= n;++ i) a[i] = read();
for(int i = 1;i <= n;++ i) b[i] = read();
for(int i = 1;i <= n;++ i) sum[i] = sum[i - 1] + b[i], cost[i] = cost[i - 1] + b[i] * i;
int l = 0,r = 0;
for(int i = 1;i <= n;++ i) {
while(l < r && slop(q[l],q[l + 1]) < i) l ++;
int t = q[l];
dp[i] = dp[t] + (sum[i] - sum[t]) * i - (cost[i] - cost[t]) + a[i];
while(l < r && slop(i,q[r]) < slop(q[r],q[r - 1])) r --;
q[++ r] = i;
}
printf("%lld
",dp[n]);
return 0;
}