HDU 1160 FatMouse‘s Speed

Posted jpphy0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1160 FatMouse‘s Speed相关的知识,希望对你有一定的参考价值。

链接

FatMouse’s Speed - http://acm.hdu.edu.cn/showproblem.php?pid=1160

分析

  • LIS
  • 动态规划
  • 寻找“越胖越慢”证据,即寻找最长链
  • 速度降序,体重升序的最长链;
  • 每个长度的链保存一条,当链的最后一个重量变化时,复制前一个长度的链
  • 另一种思路:按序列的下标分类,即每个元素一类【注意:与每个元素的值分一类的区别】

代码

等长— 值优先 【二维路径数组】

/* hdu 1160 FatMouse's Speed */
#include <bits/stdc++.h>
using namespace std;
#define MXN 1010
int dp[MXN], t[MXN][MXN];
struct FM{
	int m, s, id;
}fm[MXN];
int main(){
	int cnt = 0, len, pm;
    while(scanf("%d %d", &fm[cnt+1].m, &fm[cnt+1].s) == 2){
		cnt++;
		fm[cnt].id = cnt;
	}
	sort(fm+1, fm+cnt+1, [](FM x, FM y){ return x.s > y.s;});		
	memset(dp, 0, sizeof dp);
	memset(t, 0, sizeof t);
	len = 1, dp[1] = 1, t[1][1] = 1;
 	for(int i = 2; i <= cnt; ++i) {
		pm = lower_bound(dp+1, dp+len+1, i, [](int x, int y){
			return fm[x].m < fm[y].m;
		}) - dp;
		if(pm == len+1) len++;
		dp[pm] = i;		
		// 复制前一个链
		for(int j = 1; j < pm; ++j) t[pm][j] = t[pm-1][j];
		// 修改链的最后一个元素
		t[pm][pm] = i;
    }
	printf("%d\\n", len);
	for(int i = 1; i <= len; ++i) printf("%d\\n", fm[t[len][i]].id);
    return 0;
}

等长— 值优先 【一维前驱路径数组】

// hdu 1160 FatMouse's Speed
#include <bits/stdc++.h>
using namespace std;
#define MXN 1010
int n = 0, len, dp[MXN], pre[MXN];
struct FM{
    int w = 0, s = 0, id = 0;
    bool operator<(FM x){ return s > x.s;}
}fm[MXN];
// ostream & operator<<(ostream & os, const FM x){
//     os << "w = "<< x.w << " s = " << x.s << " id = " << x.id;
//     return os;
// }
void print(int x){
    if(x == 0) return;
    print(pre[x]);
    cout << fm[x].id << endl;
}
int main() {
    int pos;
	while(scanf("%d%d", &fm[n+1].w, &fm[n+1].s) == 2)
        n++, fm[n].id = n;
    sort(fm+1, fm+n+1);
    memset(pre, 0, sizeof pre);
    memset(dp, 0, sizeof dp);
    len = 1, dp[1] = 1;
    for(int i = 2; i <= n; ++i){
        if(fm[i].w > fm[dp[len]].w){
            pre[i] = dp[len];
            dp[++len] = i;
        }
        else{
            pos = lower_bound(dp+1, dp+len+1, i, [](int mid, int val){
                return fm[mid].w < fm[val].w;
            }) - dp;
            pre[i] = dp[pos - 1];
            dp[pos] = i;
        }
    }
	printf("%d\\n", len);
    print(dp[len]);	
	return 0;
}

按下标 — 长度优先【一维前驱路径数组】

/* hdu 1160 FatMouse's Speed */
#include <bits/stdc++.h>
using namespace std;
#define MXN 1010
int dp[MXN], pre[MXN];
struct FM{
	int m, s, id;
}fm[MXN];
int main(){
	int cnt = 0, len = 0, p;
    while(scanf("%d %d", &fm[cnt+1].m, &fm[cnt+1].s) == 2){
		cnt++;
		fm[cnt].id = cnt;
	}
	sort(fm+1, fm+cnt+1, [](FM x, FM y){ return x.s > y.s;});
	memset(dp, 0, sizeof dp);
	memset(pre, 0, sizeof pre);
 	for(int i = 1; i <= cnt; ++i) {
		for(int j = 0; j < i; ++j){
			if(fm[i].m > fm[j].m && dp[i] < dp[j]+1){
				pre[i] = j;
				dp[i] = dp[j]+1;
			}
		}
    }
	for(int i= 1; i <= cnt; ++i) if(len < dp[i]) len = dp[i], p = i;
	printf("%d\\n", len);
	cnt = len;
	while(p != 0){
		dp[cnt--] = fm[p].id;
		p = pre[p];
	}
	for(int i = 1; i <= len; ++i) printf("%d\\n", dp[i]);
    return 0;
}

以上是关于HDU 1160 FatMouse‘s Speed的主要内容,如果未能解决你的问题,请参考以下文章

HDU-1160 FatMouse's Speed

HDU 1160 FatMouse‘s Speed

HDU 1160 FatMouse's Speed (动态规划最长下降子序列)

HDU - 1160 FatMouse's Speed(dp+路径记录)

FatMouse's Speed HDU - 1160 最长上升序列,

[HDU1160]FatMouse's Speed