zoukankan      html  css  js  c++  java
  • HGOI20181031 模拟题解

    sol:第一题就DP?!然后写了O(n^2) dp再考虑优化!!!(尽量部分分带上!!!)

    我写了正确的dp然后优化错了,具体的dp方法是考虑到对于右侧到左侧他是没有后效性的

    所以定义f[i]为i及以后最大的代价和,对于合法的j,转移f[i]=max{f[j]+P[i]},j需要满足a[i]+x[i]<a[j],j>=i

    由于给出的a[i]递增然后我只要往i的右侧找到第一个合法的j然后转移就行了,复杂度O(n log n)

    我错在了用堆来优化,然后把后面的删掉了,其实可以再前面的从被误删的东西转移而来。

    code:

    # include <bits/stdc++.h>
    # ifdef O_2
    # pragma GCC optimze(2)
    # endif
    # define int long long
    using namespace std;
    const int MAXN=1e5+10;
    int f[MAXN],a[MAXN],x[MAXN],p[MAXN];
    int n;
    inline int read()
    {
        int X=0,w=0;char c=0;
        while (!(c>='0'&&c<='9')) w|=c=='-',c=getchar();
        while (c>='0'&&c<='9') X=(X<<1)+(X<<3)+(c^48),c=getchar();
        return w?-X:X;
    }
    inline void write(int x)
    {
        if (x<0) { x=-x;putchar('-');}
        if (x>9) write(x/10);
        putchar('0'+x%10);
    }
    inline void writeln(int x) { write(x);putchar('
    ');}
    signed main()
    {
        n=read();
        for (int i=1;i<=n;i++) 
          a[i]=read(),p[i]=read(),x[i]=read();
        f[n]=p[n];
        for (int i=n-1;i>=1;i--) {
            f[i]=f[i+1];
            int j=upper_bound(a+i+1,a+1+n,a[i]+x[i])-a;
            f[i]=max(max(f[i],p[i]),f[j]+p[i]);
        }  
        writeln(f[1]);
        return 0;
     }

     

    sol:这道题目对于100%的数据n,m<=3000,显然发现这一定是O(n2)的算法,

    然后如果对于X1到X2的最短路径设为R1,X3到X4最短路劲R2,要求R1和R2交的尽可能多,那么这个解一定更优

    首先一定要在最短路上,其次要求R1和R2尽可能交的更多,我们不妨设刚开始交的地方设为i,交结束的地方设为j

    我们先求出X1,X2,X3,X4到各点的最短路D1,D2,D3,D4

    我们枚举i然后再枚举j 由上图可以看出就是D1[i]+D2[j]+D3[i]+D4[j]+dist(i,j)在枚举j之前我们可以O(n)求出i的最短路D5

    那么就是最小化D1[i]+D2[j]+D3[i]+D4[j]+D5[j],

    然后我们交换(X1,X2)or (X3,X4) 之中的任意一对然后再求min,就是D1[i]+D2[j]+D3[j]+D4[i]+D5[j],

    然后对于每一次枚举Ans=Min(D1[i]+D2[j]+D3[i]+D4[j]+D5[j],D1[i]+D2[j]+D3[j]+D4[i]+D5[j],ans)

    对于一个显然的情况我们最后特判就是直接 X1走到X2,X3 走到 X4 最短路虽然并没有重复的路 即 ans=Min(ans,D1[X2]+D3[X4]);

    code:

    # include <bits/stdc++.h>
    # ifdef O_2
    # pragma GCC optimze(2)
    # endif
    using namespace std;
    const int MAXN=3005;
    int n,m,X1,X2,X3,X4;
    int D1[MAXN],D2[MAXN],D3[MAXN],D4[MAXN],D5[MAXN];
    int tot=0,head[MAXN];
    bool vis[MAXN];
    struct rec{ int pre,to,w;}a[MAXN*2];
    inline int read()
    {
        int X=0,w=0;char c=0;
        while (!(c>='0'&&c<='9')) w|=c=='-',c=getchar();
        while (c>='0'&&c<='9') X=(X<<1)+(X<<3)+(c^48),c=getchar();
        return w?-X:X;
    }
    inline void write(int x)
    {
        if (x<0) { x=-x;putchar('-');}
        if (x>9) write(x/10);
        putchar('0'+x%10);
    }
    inline void writeln(int x) { write(x);putchar('
    ');}
    void adde(int u,int v,int w)
    {
        a[++tot].pre=head[u];
        a[tot].to=v;
        a[tot].w=w;
        head[u]=tot;
    }
    struct node{ int id,dist;};
    int d[MAXN];
    queue<node>q;
    void bfs(int s)
    {
        memset(vis,false,sizeof(vis));
        memset(d,0x3f,sizeof(d));
        d[s]=0; vis[s]=1;
        q.push((node){s,0});
        while (!q.empty()) {
            node u=q.front();q.pop();
            for (int i=head[u.id];i;i=a[i].pre) {
                int v=a[i].to;
                if (vis[v]) continue;
                vis[v]=1;
                d[v]=u.dist+1;
                q.push((node){v,d[v]});
            }
        } 
    }
    int Min(int a,int b,int c)
    {
        if (b<a) a=b;
        if (c<a) a=c;
        return a;
    }
    int main()
    {
        n=read();m=read();
        X1=read();X2=read();X3=read();X4=read();
        int u,v;
        for (int i=1;i<=m;i++) {
            u=read();v=read();
            adde(u,v,1); adde(v,u,1);
        }
        bfs(X1); memcpy(D1,d,sizeof(d));
        bfs(X2); memcpy(D2,d,sizeof(d));
        bfs(X3); memcpy(D3,d,sizeof(d));
        bfs(X4); memcpy(D4,d,sizeof(d));
        int ans=m;
        for (int i=1;i<=n;i++) {
            bfs(i); memcpy(D5,d,sizeof(d));
        for (int j=1;j<=n;j++) 
          ans=Min(ans,D1[i]+D3[i]+D2[j]+D4[j]+D5[j],D1[i]+D4[i]+D3[j]+D2[j]+D5[j]);
        }
        ans=min(ans,D1[X2]+D3[X4]);
        writeln(ans);
        return 0;
     }
  • 相关阅读:
    创建Hive/hbase相关联的表异常
    CDH5.2+CM5.2+impala2+Spark1.1 集群搭建基础环境准备
    【JavaWeb】(10)微信公众号开发进阶
    Ambari-stack介绍
    OSGi中的ServletContext
    笔试面试1 用C实现C库函数itoa, atoi
    SGU 114. Telecasting station 三分or找中位数
    face++实现人脸识别
    磁盘接口与磁盘扫描
    CSDN开源夏令营 百度数据可视化实践 ECharts(4)
  • 原文地址:https://www.cnblogs.com/ljc20020730/p/9882489.html
Copyright © 2011-2022 走看看