• Luogu P1052 过河


    思路

    动态规划不用说,而且这道题的转移方程非常简单,连我都能推出来。难就难在怎么去优化空间和时间。因为$large{Lle 10^9}$,直接开数组的话不仅空间会炸的连渣都不剩,而且枚举的时候时间也会炸的连渣都不剩。看了题解后,我感到了世界对我的恶意我好弱鸡。用离散化的方法缩小复杂度。

    输入之后将石头的位置排序。首先保证它们是递增的,那么相邻的两个石头之间肯定没有其他石头了。所以相邻的两个石头坑定能通过$large{tx+(a[i]-a[i-1])\%t}$走出来,但是我们根本不用考虑x,直接看做$1$,那么数组的大小数组的大小就变成了$large{2*t*m}$。明显的小了不少。

    状态转移方程

    $$large{dp[i] = min(dp[i], dp[i-j]+flag[i-j]), sle jle t}$$

    代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    int m, L, s, t, dp[2500], a[105], cnt, ans = 2147483647;
    bool flag[2500];
    
    int main() {
    	scanf("%d%d%d%d", &L, &s, &t, &m);
    	memset(dp, 0x3f, sizeof(dp));
    	for(int i=1; i<=m; i++) {
    		scanf("%d", &a[i]);
    	}
    	a[m+1] = L;
    	sort(a, a+2+m);
    	for(int i=1; i<=m+1; i++) {
    		if(a[i] - a[i-1] > t)
    			cnt += (a[i]-a[i-1]) % t + t;
    		else cnt += a[i]-a[i-1];
    		flag[cnt] = true;
    	}
    	flag[cnt] = 0, flag[0] = 0, dp[0] = 0;
    	for(int i=1; i<=cnt+t+1; i++) {
    		for(int j=s; j<=t && i-j>=0; j++) {
    			dp[i] = min(dp[i], dp[i-j]+flag[i-j]);
    		}
    	}
    	for(int i=cnt; i<=cnt+t; i++) {
    		ans = min(dp[i], ans);
    	}
    	printf("%d", ans);
    }
    

      

  • 相关阅读:
    TopShelf注册win10 服务
    win 10服务简单注册
    关于Win10 的服务注册
    泛型 Generic
    数据转换成字符串格式
    蛋白粉怎么吃
    6 ways to Sort Pandas Dataframe: Pandas Tutorial
    GET and POST requests using Python
    python中安装包出现Retrying, 国内pip源提示“not a trusted or secure host”解决
    Anaconda 4.7.5
  • 原文地址:https://www.cnblogs.com/bljfy/p/9333825.html
Copyright © 2020-2023  润新知