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

    每行一个线段,必须要走完,显然可以发现从左往右走完或者从右往左走完是比较优的。从中间往下走浪费步数??(好像可以,但是我理解不来,也找不到有人这样写)
    那么是该从左往右还是从右往左呢。我们需要枚举了。这个状态又有最优子结构,这时候需要优雅的暴力--DP。

    (f[i][0])表示走完第i行的线段,并且在该线段左边时的最小步数
    (f[i][1])表示走完第i行的线段,并且在该线段右边时的最小步数

    (f[i][0/1])可以从(f[i-1][1/0])得出,分类讨论即可。
    关于为什么这样走最优,可以画图自己平移下

    
    #include<bits/stdc++.h>
    #define rep(i,j,k) for(register int i(j);i<=k;++i)
    #define drp(i,j,k) for(register int i(j);i>=k;--i)
    using namespace std;
    typedef long long lxl;
    template<typename T> 
    inline T  max(T &a, T &b) {
    	return a > b ? a : b;
    }
    template<typename T> 
    inline T  min(T &a, T &b) {
    	return a < b ? a : b;
    }
    
    inline char gt() {
    	static char buf[1 << 21], *p1 = buf, *p2 = buf;
    	return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
    }
    template <typename T>
    inline void  read(T &x) {
    	register char ch = gt();
    	x = 0;
    	int w(0);
    	while(!(ch >= '0' && ch <= '9'))w |= ch == '-', ch = gt();
    	while(ch >= '0' && ch <= '9')x = x * 10 + (ch & 15), ch = gt();
    	w ? x = ~(x - 1) : x;
    }
    template <typename T>
    inline void out(T x) {
    	if(x < 0) x = -x, putchar('-');
    	char ch[20];
    	int num(0);
    	while(x || !num) ch[++num] = x % 10 + '0', x /= 10;
    	while(num) putchar(ch[num--]);
    	putchar('
    ');
    }
    const int N=2e4+79;
    int L[N],R[N]; 
    int f[N][2];
    int n;
    
    inline int dis(int a,int b){
    	return abs(a-b);
    }
    
    int main() {  
       read(n);
       rep(i,1,n) {
       	read(L[i]);read(R[i]);
       }
       memset(f,0x3f,sizeof f);
       f[1][1]=R[1]-1;
       f[0][1]=R[1]-1+(R[1]-L[1]);
       
       rep(i,2,n){
       	f[i][1]=min(f[i-1][1]+dis(R[i-1],L[i])+dis(L[i],R[i]),f[i-1][0]+dis(L[i-1],L[i])+dis(L[i],R[i]))+1;
       	f[i][0]=min(f[i-1][1]+dis(R[i-1],R[i])+dis(R[i],L[i]),f[i-1][0]+dis(L[i-1],R[i])+dis(L[i],R[i]))+1;
       }
       out(min(f[n][1]+dis(R[n],n),f[n][0]+dis(L[n],n)));
    	return 0;
    }
    
    

    当然这题也可以跑最短路。。网格图。要学会一题多解(强行增加时间复杂度,但是可以增强编程能力)
    增强建图能力(乱搞)
    去luogu看吧,懒得写了

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15191564.html

  • 相关阅读:
    ST表——————一失足成千古恨系列2
    五一清北学堂培训之图论
    最长上升子序列的教训———一失足成千古恨系列1
    五一清北学堂培训之Day 3之DP
    [bzoj1057][ZJOI2007]棋盘制作
    [bzoj1010][HNOI2008]玩具装箱TOY
    [bzoj2326][HNOI2011]数学作业
    如何使用矩阵乘法加速动态规划——以[SDOI2009]HH去散步为例
    [bzoj1060][zjoi2007]时态同步
    [bzoj1046][HAOI2007]上升序列
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15191564.html
Copyright © 2011-2022 走看看