zoukankan      html  css  js  c++  java
  • 【每日一题】27. 过河 (DP + 离散化)

    补题链接:Here

    算法涉及:DP + 离散化

    (l) 的范围太大,无法作为数组下标,所以先离散化,再DP。两点间的距离d大于t时,一定可以由 (d \% t) 跳过来,所以最多只需要t+d%t种距离的状态就可以表示这两个石子之间的任意距离关系。这样就把题目中的 (10^9) 压缩成了(2*t*m) 最多不超过 (2000) ,然后就可以放心大胆地用DP了。不过要注意题目中的“当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥”,所以DP的终点是一个范围而非确切的一个点,最后还要在这个范围内取最小值。

    using ll = long long;
    const int N = 1e6 + 10;
    const ll inf = 0x3f3f3f3f;
    ll dp[N], a[N], vis[N];
    void solve() {
    	int l, s, t, m;
    	cin >> l >> s >> t >> m;
    	for (int i = 1; i <= m; ++i)cin >> a[i];
    	sort(a + 1, a + 1 + m);
    	a[0] = 0, a[m + 1] = l;
    	int tmp = 0;
    	for (int i = 1; i <= m + 1; ++i) {
    		//这里一定要在取模后加t,否则会WA
    		if (a[i] - a[i - 1] > t)tmp += (a[i] - a[i - 1]) % t + t;
    		else tmp += a[i] - a[i - 1];
    		vis[tmp] = 1; //表示此处有石子
    	}
    	memset(dp, 0x3f, sizeof(dp));
    	dp[0] = 0;
    	for (int i = 1; i <= tmp + 100; ++i)
    		for (int j = s; j <= t; ++j)
    			if (i >= j)dp[i] = min(dp[i], dp[i - j] + vis[i]);
    	ll ans = inf;
    	//终点可能的范围,稍微写大点·
    	for (int i = tmp; i <= tmp + 100; ++i)
    		ans = min(ans, dp[i]);
    	cout << ans;
    }
    
    

    The desire of his soul is the prophecy of his fate
    你灵魂的欲望,是你命运的先知。

  • 相关阅读:
    像画笔一样慢慢画出Path的三种方法(补充第四种)
    占位符行为 PlaceHolderBehavior 的实现以及使用
    WPF实现物理效果 拉一个小球
    WPF实现Twitter按钮效果
    WPF自适应可关闭的TabControl 类似浏览器的标签页
    WPF仿百度Echarts人口迁移图
    WPF绘制简单常用的Path
    51Nod 1534 棋子游戏
    数论基础
    Buy a Ticket
  • 原文地址:https://www.cnblogs.com/RioTian/p/14773808.html
Copyright © 2011-2022 走看看