您的位置:首页 > 其它

UVA 10131 - Is Bigger Smarter

2011-05-13 16:42 288 查看
题目大意: 给出一些大象,包含它的重量、智商。要你找出最长的序列,满足重量越大、智商越低。(严格增减)

题目类型:dp / LIS

题目分析:

把大象按重量升序排序,然后在此序列中对智商属性找最长单减子序列。要注意的是,题目要求的都是严格增减,所以要在判断条件里考虑相等的情况以排除(主要是重量)。

另外还要注意,排序后,序就不是原来的序了,而题目要求输出原序。所以在排序时维护一个r[]数组。

对于 最长单减子序列 的dp,状态转移方程(2种):

//d[i] = max{d[j]+1 | s[i]>s[j]; j = (i, n);} //d[i] 表示以 i 开头的 最长 递减子序列
//d[i] = max{d[j]+1 | s[i]<s[j]; j = [0, i);} //d[i] 表示以 i 结尾的 最长 递减子序列

代码:

]#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAXN 1002
struct ele
{
int w, s;
int next;
int xh;
}e[MAXN];
int r[MAXN];	//用于保留对应的原序
int n;
int d[MAXN];
int vis[MAXN];
//d[i] = max{d[j]+1 | s[i]>s[j]; j = (i, n);}		//d[i] 表示以 i 开头的 最长 递减子序列
//d[i] = max{d[j]+1 | s[i]<s[j]; j = [0, i);}		//d[i] 表示以 i 结尾的 最长 递减子序列
int dp(int cur)	//以cur,做开头
{
if(vis[cur]) return d[cur];
vis[cur] = 1;
int max = 1;
for(int i=cur+1; i<n; i++)
if(e[i].s<e[cur].s && e[i].w>e[cur].w)	//找降序		//注意w 严格增 ②
{
int t = dp(i)+1;
max = max>t? max: (e[cur].next = i, t);
}
return d[cur] = max;
}
void print(int x)
{	//d[x] = 1 说明 停止
while(1)
{
printf("%d/n", e[x].xh+1);		//从1开始,④
///////////	debug
//		printf("w=%d, iq=%d/n", e[x].w, e[x].s);
if(d[x]==1) break;
x = e[x].next;
}
}
int cmp(ele a, ele b)	//sort 中 参数 完全可以不用是 const 用于改值,很好用!	③
{
if(a.w<b.w)
{
return 1;
}
else
{
int t = a.xh;
a.xh = b.xh;
b.xh = t;
return 0;
}
}
int main()
{
n=0;
for(int i=0; scanf("%d%d", &e[i].w, &e[i].s)!=EOF; i++, n++)
{
e[i].xh = i;
}
sort(e, e+n, cmp);	//按 w 升序
memset(vis, 0, sizeof(vis));
int max = 1;
int ans;
for(int i=0; i<n; i++)
{
max  = max > dp(i)? max: (ans = i, dp(i));
}
printf("%d/n", max);
print(ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: