城市交通
jzoj 1749
题目大意
有n个点,x到y的前提是x<y,代价是 ,问从1到n的最小代价是多少
输入样例
4
2 9 5 4
9 1 2 2
输出样例
8
数据范围
对于20%的数据,
对于50%的数据,
对于100%的数据,
解题思路
y要大于x,就说明不能倒着走,那就可以用DP来做
我们设
为到从1到i的最小代价,如果我们直接枚举从哪里来,那时间复杂度就是
,那就会TLE
那我们考虑优化
我们可以用单调队列来存有用的状态
有用的状态(i)对比前面所有有用的状态(j)都必须满足以下两个条件之一
1:、
2、
这样才可能使答案更优
后面的状态只须从有用的状态转移
当然这样还是可能被卡,但数据太水,A了
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n, w, p, a[100500], b[100500], f[100500], k[100500];
int main()
{
scanf("%lld", &n);
for (ll i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
for (ll i = 1; i <= n; ++i)
scanf("%lld", &b[i]);
memset(f, 127/3, sizeof(f));
f[1] = 0;
k[++w] = 1;//有用的状态
for (ll i = 2; i <= n; ++i)
{
p = 1;
for (int j = 1; j <= w; ++j)
{
f[i] = min(f[i], f[k[j]] + a[k[j]] * (i - k[j]) + b[i]);//转移
if (a[i] > a[k[j]] && b[i] > b[k[j]]) p = 0;//判断是否是有用的状态
}
if (p)
k[++w] = i;//加入
}
printf("%lld", f[n]);
return 0;
}
注:
这道题还可以用斜率优化做,但本蒟蒻还要学习学习