zoukankan      html  css  js  c++  java
  • #洛谷 P3842 [TJOI2007]线段

    P3842 [TJOI2007]线段


    思路

    1.出发点

    显然显然显然(重要的事情说三遍),这一行的终点可能是线段的左边也可能是线段的右边,所以要想走完这一行的线段,就需要从上一行的左端点或右端点,进而就有了下面的讨论

    2.讨论

    计f[0][i]为走完第i行的线段且

    情况1:上一行线段在左,下一行线段在右

    此时分两种图:


    很显然,这两种可能可以合并

    第一种图:

    图1:

    这里指出一个误区:明明线路(2)比线路(1)要优秀,为什么还要考虑呢?其实很简单,(f[0][i-1])可能要比(f[1][i-1])小很多,而不是(f[1][i-1])一定大于(f[0][i-1]),所以(f[0][i-1]+abs(r[i]-l[i-1]))(从上一行左端点到这一行右端点)可能小于(f[1][i-1]+abs(r[i-1]-r[i]))(从上一行右端点到这一行右端点)

    图2:

    状态转移方程为:

      f[0][i]=min(f[0][i-1]+abs(r[i]-l[i-1]),f[1][i-1]+abs(r[i-1]-r[i]))+len[i]+1;
      f[1][i]=min(f[0][i-1]+abs(l[i-1]-l[i]),f[1][i-1]+abs(r[i-1]-l[i]))+len[i]+1;
    

    第二种图:

    图1:

    图2:

    状态转移方程为:

      f[0][i]=min(f[0][i-1]+abs(r[i]-l[i-1]),f[1][i-1]+abs(r[i-1]-r[i]))+len[i]+1;
      f[1][i]=min(f[0][i-1]+abs(l[i-1]-l[i]),f[1][i-1]+abs(r[i-1]-l[i]))+len[i]+1;
    

    惊奇的发现,状态转移方程竟然一样,这样就减少判断缩减了代码

    情况2:上一行线段在中,下一行线段在中

    此时也分两种图:


    显然这两种也可以合并

    同样四张图:




    状态转移方程:

      f[0][i]=min(f[0][i-1]+abs(r[i]-l[i-1]),f[1][i-1]+abs(r[i-1]-r[i]))+len[i]+1;
      f[1][i]=min(f[0][i-1]+abs(l[i-1]-l[i]),f[1][i-1]+abs(r[i-1]-l[i]))+len[i]+1;
    

    我们又要口矣了,两种大情况的状态转移方程也一样诶,显然第三种情况(上一行线段在右,下一行线段在左)也是这个状态转移方程,都可以合并就不用判断了诶诶诶(当然可以自己在画画第三种情况的图)

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=2e4+5,INF=0x3f3f3f3f,mol=1000007;
    int n,m,f[2][maxn],a[maxn],l[maxn],r[maxn],len[maxn];
    inline int read(){
    	int s=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    	return s*w;
    }
    int main(){
    	//freopen("a.in","r",stdin);
    	n=read();
    	for(int i=1;i<=n;i++)l[i]=read(),r[i]=read(),len[i]=r[i]-l[i];
    	f[0][1]=r[1]-1+len[1];f[1][1]=r[1]-1;
    	for(int i=2;i<=n;i++){
    		f[0][i]=min(f[0][i-1]+abs(r[i]-l[i-1]),f[1][i-1]+abs(r[i-1]-r[i]))+len[i]+1;
    		f[1][i]=min(f[0][i-1]+abs(l[i-1]-l[i]),f[1][i-1]+abs(r[i-1]-l[i]))+len[i]+1;
    	}
    	cout<<min(f[0][n]+n-l[n],f[1][n]+n-r[n]);
    	
    }
    

    OVER~

  • 相关阅读:
    JMeter的JavaRequest探究
    记一次生产压测遇到的"坑"
    JMeter之If Controller深究二
    JMeter之SteppingShape
    那些年拿过的shell之adminer
    Spring Boot Actuator H2 RCE复现
    使用sqlmap结合dnslog快速注入
    一次稍显曲折的爆破经历
    无回显、不出网命令执行测试方式
    实战绕过某waf后缀检测内容检测
  • 原文地址:https://www.cnblogs.com/614685877--aakennes/p/13301577.html
Copyright © 2011-2022 走看看