zoukankan      html  css  js  c++  java
  • 龙珠雷达 双指针+DP

    龙珠雷达 双指针+DP
    你得到了一个龙珠雷达,它会告诉你龙珠出现的时间和地点。
       龙珠雷达的画面是一条水平的数轴,每一个窗口时间,数轴的某些点上会出现同一种龙珠,每当你获得其中一颗龙珠,其它龙珠就会消失。下一个窗口时间,数轴上又会出现另一种龙珠。总共有n个窗口时间,也就是总共有n种龙珠。
      假设你会瞬间移动,你从数轴的x点移动到y点,耗时0秒,但是需要耗费|x-y|的体力。同时,挖出一颗龙珠也需要耗费一定的体力。请问,最少耗费多少体力,就可以收集齐所有种类的龙珠。

    解:
    方程我就不说了 详见代码
    话说我开先想的居然是 最短路 然后空间还算错 导致MLE
    真是zz

    这里主要说优化

    首先注意到 为了让i-1层的(dis(k)<dis(j)) 我们需要找最小的满足条件的 随着第i层j的线性增加$ dis(k) $的范围越来越大
    所以可以考虑 双指针求极值
    code:

    //
    #include<iostream>
    #include<cstdio>
    #include<stdio.h>
    #include<cmath>
    #include<algorithm>
    #include<cstdlib>
    #include<queue>
    #define ll long long
    using namespace std;
    #define maxnn 10005
    
    ll f[55][maxnn];
    ll w[55][maxnn];
    struct node
    {
        ll x, y;
    } mapp[55][maxnn];
    int n,m,x;
    bool cmp(node a,node b)
    {
        return a.x<b.x;
    }
    int main()
    {
        cin>>n>>m>>x;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%lld",&mapp[i][j].x);
            }
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                scanf("%lld",&mapp[i][j].y);
            }
        for(int i=1;i<=n;i++)
            sort(mapp[i]+1,mapp[i]+1+m,cmp);
        for(int j=1;j<=m;j++)
        {
            f[1][j]=abs(mapp[1][j].x-x)+mapp[1][j].y;
        }
        for(int i=2;i<=n;i++)
        {
            ll index=1;
            ll ans=11111111100;
            for(ll j=1;j<=m;j++)
            {
                f[i][j]=10000000000;
                while(mapp[i][j].x>=mapp[i-1][index].x&&index<=m)
                {
                    ans=min(ans,f[i-1][index]-mapp[i-1][index].x);
                    index++;
                }
                f[i][j]=min(ans+mapp[i][j].y+mapp[i][j].x,f[i][j]);
            }
            index=m;
            ans=10000000000;
            for(int j=m;j>=1;j--)
            {
                while(mapp[i][j].x<=mapp[i-1][index].x&&index>=1)
                {
                    ans=min(ans,f[i-1][index]+mapp[i-1][index].x);
                    index--;
                }
               
                f[i][j]=min(ans+mapp[i][j].y-mapp[i][j].x,f[i][j]);
            }
        }
        ll ans=11111111000;
        for(int i=1;i<=m;i++)
            ans=min(ans,f[n][i]);
        cout<<ans;
        
    }
    
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    vs 2005 使用 UpdatePanel 配置
    gridview checkbox 列
    csv 格式文件 导入导出
    UML中数据流图,用例图,类图,对象图,角色图,活动图,序列图详细讲述保存供参考
    c# 根据经纬度 求两点之间的距离
    c# 加密汇总
    日期获取 第一天,最后一天
    求点到直线的垂足
    c# 修改注册表
    HDOJ_1548 上楼梯 DJ
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11565085.html
Copyright © 2011-2022 走看看