zoukankan      html  css  js  c++  java
  • 洛谷 P1052 [NOIP2005 提高组] 过河(dp,数学)

    传送门


    解题思路

    很巧妙的一个题。
    朴素的dp方程肯定都能列出来,关键是离散化如何操作。
    可以仿照NOIP2017D1T1小凯的疑惑,将两个石头之间距离>=(st-s-t)全部转化为(st-s-t)。
    可以理解为若距离>=(st-s-t),则所有的点都能到达。
    但是这题要求宽松,方便又保险起见,把距离限度设置为s
    t也可以稳过。

    AC代码

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    #include<set>
    #include<map>
    #include<vector>
    #include<iomanip>
    #include<ctime>
    #include<stack>
    using namespace std;
    const int maxn=2e6+5;
    int n,m,s,t,l,a[maxn],d[maxn],vis[maxn],ans=1e5,dp[maxn];
    int main()
    {
    	ios::sync_with_stdio(false);
    	memset(dp,0x3f,sizeof(dp));
    	dp[0]=0;
    	cin>>l>>s>>t>>m;
    	for(int i=1;i<=m;i++) cin>>a[i];
    	sort(a+1,a+m+1);
    	if(s==t){
    		int cnt=0;
    		for(int i=1;i<=m;i++) if(a[i]%s==0) cnt++;
    		cout<<cnt;
    		return 0;
    	}
        for(int i=1;i<=m;i++){
        	if(a[i]-a[i-1]>s*t) d[i]=d[i-1]+s*t;
        	else d[i]=d[i-1]+a[i]-a[i-1];
        	vis[d[i]]=1;
    	}
    	n=s*t*m+t;
    	for(int i=1;i<=n;i++){
    		for(int j=s;j<=t;j++){
    			if(i>=j) dp[i]=min(dp[i],dp[i-j]+vis[i]);
    		}
    		if(i>=d[m]) ans=min(ans,dp[i]);
    	}
    	cout<<ans;
        return 0;
    }
    

    //NOIP2005提高组 t2

  • 相关阅读:
    hdu4472-Count
    Codeforces Beta Round #55 (Div. 2)
    优化素数表
    Codeforces Beta Round #49 (Div. 2)-D. Physical Education
    Codeforces Beta Round #49 (Div. 2)-C. Little Frog
    一些不知道的函数
    kmp算法详解
    STL之accumulate用法小结
    STL——list学习笔记
    maven打war包包含源文件-eclipse
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15086183.html
Copyright © 2011-2022 走看看