zoukankan      html  css  js  c++  java
  • 洛谷 P1052 过河 (离散化+dp)

    dp非常好想, f[i] = min(f[i-len] + stone[i]) s <= len <= t
    然后因为L非常大,所以我就不知道该怎么搞了
    我看到m只有100,而L有1e9,我就知道肯定要通过某种数学方法来离散化
    然而我并没有想出来这个数学方法

    看来题解,原来这个方法很简单,我怎么就没有想到
    因为最大走10步,所以把距离对1到10的最小公倍数是2520取模就好了。
    离散化之后就可以愉快地dp了

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    #define _for(i, a, b) for(int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXM = 312345;
    const int MAXN = 112;
    int f[MAXM], a[MAXN], d[MAXN];
    int stone[MAXM], s, t, n, L;
    
    int main()
    {
    	scanf("%d%d%d%d", &L, &s, &t, &n);
    	_for(i, 1, n) scanf("%d", &a[i]);
    	sort(a + 1, a + n + 1);
    	
    	_for(i, 1, n) d[i] = (a[i] - a[i-1]) % 2520;
    	_for(i, 1, n) a[i] = a[i-1] + d[i], stone[a[i]] = 1;
    	L = a[n];
    	
    	memset(f, 0x3f, sizeof(f));
    	f[0] = 0;
    	_for(i, 1, L + t)
    		_for(len, s, min(i, t))
    			f[i] = min(f[i], f[i-len] + stone[i]);
    	
    	int ans = 1e8;
    	_for(i, L, L + t)
    		ans = min(ans, f[i]);
    	printf("%d
    ", ans);
    	
    	return 0;
    }

    当然还有更好的优化方式

    当距离小于t时保持不变,大于t时,改成d % t + t(一定要再加上t!!!)

    我一开始是有想到,但是我想到还有s,s+1等
    说实话不用想得这么完美,直接用最大的t模就好了。

    这样空间可以开小很多。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define REP(i, a, b) for(int i = (a); i < (b); i++)
    #define _for(i, a, b) for(int i = (a); i <= (b); i++)
    using namespace std;
    
    const int MAXM = 2123;
    const int MAXN = 112;
    int f[MAXM], a[MAXN], d[MAXN];
    int stone[MAXM], s, t, n, L;
    
    int main()
    {
    	scanf("%d%d%d%d", &L, &s, &t, &n);
    	_for(i, 1, n) scanf("%d", &a[i]);
    	sort(a + 1, a + n + 1);
    
    	_for(i, 1, n) 
    	{
    		d[i] = a[i] - a[i-1];
    		if(d[i] > t) d[i] = (d[i] % t) + t; 
    	}
    	_for(i, 1, n) a[i] = a[i-1] + d[i], stone[a[i]] = 1;
    	L = a[n];
    	
    	memset(f, 0x3f, sizeof(f));
    	f[0] = 0;
    	_for(i, 1, L + t)
    		_for(len, s, min(i, t))
    			f[i] = min(f[i], f[i-len] + stone[i]);
    	
    	int ans = 1e8;
    	_for(i, L, L + t)
    		ans = min(ans, f[i]);
    	printf("%d
    ", ans);
    	
    	return 0;
    }
  • 相关阅读:
    关于jquery尺寸的总结
    PhotoshopCC 如何使用动作文件ATN
    改变radio默认样式
    html中如何修改选中 用input做的搜索框 的边框颜色
    option触发事件两种方法总结
    用 CSS 隐藏页面元素的 5 种方法
    bootstrap模态框总结
    stop总结
    如何解决在chrome中自动完成表单后input出现黄色背景
    jquery实现显示和隐藏toggle()方法的使用
  • 原文地址:https://www.cnblogs.com/sugewud/p/9819378.html
Copyright © 2011-2022 走看看