码迷,mamicode.com
首页 > 其他好文 > 详细

【文文殿下】 [USACO08MAR]土地征用 题解

时间:2019-01-17 23:50:51      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:inline   lse   cout   typedef   std   c++   ++i   ++   rev   

题解

斜率优化裸题。

有个很玄学的事情,就是我用\(f[i]=min\{f[j-1]+p[j].y*p[i].x\}\) 会很奇怪的Wa 。 明明和\(f[i]=min\{f[j]+p[j+1].y*p[i].x\}\)一模一样的呀!

如果有dalao愿意帮忙看一下就感激不尽了。

附上正确代码和错误代码

正确代码:

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

const int maxn = 5e4+10;
const ll inf = 10000000000000LL;
struct qwq{
    ll x,y;
    const bool operator < (const qwq rhs) const {
        if(this->x==rhs.x) 
            return this->y<rhs.y;
        return this->x<rhs.x;
    }
} tmp[maxn],p[maxn];
ll f[maxn];
int tot=0,n,q[maxn],l,r;
long double slope(int a,int b) {
    long double tmp1 = f[b]-f[a],tmp2 = -p[b+1].y+p[a+1].y;
    return tmp1/tmp2;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i = 1;i<=n;++i) 
        cin>>tmp[i].x>>tmp[i].y;
    sort(tmp+1,tmp+1+n);
    ll mxy=0;
    for(int i = n;i;--i) {
        if(tmp[i].y>mxy) {
            mxy=tmp[i].y;
            p[++tot]=tmp[i];
        }
    }
    reverse(p+1,p+1+tot);
#ifdef force
    for(int i = 1;i<=tot;++i) {
        f[i]=inf;
        for(int j = 0;j<i;++j) {
            f[i]=min(f[i],f[j]+p[j+1].y*p[i].x);
        }
    }
#endif
#ifndef force
    for(int i = 1;i<=tot;++i) {
        while(l<r&&slope(q[l],q[l+1])<=p[i].x) ++l;
        int j = q[l];
        f[i]=f[j]+p[j+1].y*p[i].x;
        while(l<r&&slope(q[r-1],q[r])>=slope(q[r],i)) --r;
        q[++r]=i;
    }
#endif
    cout<<f[tot]<<endl;
    return 0;
}

错误代码

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

const int maxn = 5e4+10;
const ll inf = 10000000000000LL;
double esp = 1e-6;
struct qwq{
    ll x,y;
    const bool operator < (const qwq rhs) const {
        if(this->x==rhs.x) 
            return this->y<rhs.y;
        return this->x<rhs.x;
    }
} tmp[maxn],p[maxn];
ll f[maxn];
int tot=0,n,q[maxn],l,r;
double slope(int a,int b) {
    double tmp1 = f[b-1]-f[a-1],tmp2 = -p[b].y+p[a].y;
    return tmp1/tmp2;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i = 1;i<=n;++i) 
        cin>>tmp[i].x>>tmp[i].y;
    sort(tmp+1,tmp+1+n);
    ll mxy=0;
    for(int i = n;i;--i) {
        if(tmp[i].y>mxy) {
            mxy=tmp[i].y;
            p[++tot]=tmp[i];
        }
    }
    reverse(p+1,p+1+tot);
#ifdef force
    for(int i = 1;i<=tot;++i) {
        f[i]=inf;
        for(int j = 1;j<=i;++j) {
            f[i]=min(f[i],f[j-1]+p[j].y*p[i].x);
        }
    }
#endif
#ifndef force
    l=r=1;
    q[1]=1;
    for(int i = 1;i<=tot;++i) {
        while(l<r&&slope(q[l],q[l+1])<=p[i].x) ++l;
        int j = q[l];
        f[i]=f[j-1]+p[j].y*p[i].x;
        while(l<r&&slope(q[r-1],q[r])>=slope(q[r],i)) --r;
        q[++r]=i+1;
    }
#endif
    cout<<f[tot]<<endl;
    return 0;
}

【文文殿下】 [USACO08MAR]土地征用 题解

标签:inline   lse   cout   typedef   std   c++   ++i   ++   rev   

原文地址:https://www.cnblogs.com/Syameimaru/p/10284869.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!