hdu 1160 fat mouse‘s speed

对于我的难点来讲是输出最长上升子序列(某一个),在这里用到了标记,用数组标记以当前数为结尾的最长上升子序列的前一个数,以我个人浅陋的见解,认为这是有记忆化搜索思想的。

/*  fat mouse’s speed
 *  1.降低维度,排序将重量维度消掉
 *  2.输出最长的上升子序列长度,同时将上升子序列输出
 *  这一点我个人认为用到了记忆化搜索,跟动态规划相关性不强
 *  (1).不知道哪一组数会成为最长的上升子序列,则将所有数据对应的上一个数据进行标记
 *  (2).最终利用已知的最后一只老鼠进行结果保存,同时保证正序输出
 */
#include<iostream>
#include<algorithm>
#include<string.h>
int index[1010];
int pos[1010];
int dp[1010];
using namespace std;
struct mouse 
{
	int weight;
	int speed;
	int num;
}a[1010];
bool cmp(mouse a, mouse b) 
{
	if (a.weight == b.weight)return a.speed > b.speed;
	return a.weight < b.weight;
}
int main()
{
	int i = 1,j;
	//对于多循环来讲,早定义能够使代码简洁(小细节)
	while (cin >> a[i].weight >> a[i].speed)
	{
		a[i].num = i;
		index[i] = 0;
		/* 帮助后面输出数组时能够终止
		 * 相应编号所指代的前一个数为0,则终止输出(终止条件)
		*/
		i++;
	}
	sort(a, a + i, cmp);
	int ans = 1, maxi;
	int n = i - 1;
	//ans用来记录最大上升子序列个数
	//end用来记录最后一个元素指代,从而能够用数组存储
	for (i = 1; i <= n; i++)
	{
		dp[i] = 1;
		for (j = 1; j < i; j++)
		{
			if (a[i].weight > a[j].weight && a[i].speed < a[j].speed&& dp[j] + 1 > dp[i])
				{
					dp[i] = dp[j] + 1;
					index[i] = j;
					//用来指代上一个元素,这样的话,每一个元素对应的上升部分都会被得到标记
				//注意,最长上升部分需要利用状态转移方程标记,切记最长!
				}
			if (ans < dp[i])
			{
				ans = dp[i];
				maxi = i;
//选取最后一个目标元素,也就是最大的那一个,这样,因为之前都被标记,所以能够输出
			}
		}
	}
	int t = maxi;
	i = 0;
	//想要按初始顺序输出的话再找一个数组存入
	while(t)
	{
		pos[i++] = t;
		//pos[i]++=index[t],我刚开始写成这个,找错误找了一天,无语
		t = index[t];
	}
	cout << i << endl;
	while(i>0)
	{
		i--;
		cout << a[pos[i]].num << endl;
	}
	/* while(i-->0)
	 * 也可以改写成这样,充分利用i--的后效性
	 * 效果:1.在当时不进行减法,同时能够输出相应的-1元素
	 *       2.在最后一次,能够输出a[pos[0]].num且不终止循环
    */
}
上一篇:TGraphicControl如何捕获鼠标滚轮事件(WMMouseWheel)


下一篇:Vs code如何设置Ctrl+滚轮放大和缩小代码?