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

龙珠雷达 双指针+DP

时间:2019-09-21 23:06:45      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:mes   queue   出现   amp   def   dex   iostream   导致   fine   

龙珠雷达 双指针+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;
    
}

龙珠雷达 双指针+DP

标签:mes   queue   出现   amp   def   dex   iostream   导致   fine   

原文地址:https://www.cnblogs.com/OIEREDSION/p/11565085.html

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