SCAU--ACM专题训练II - DP---B-- Is Bigger Smarter?

题目描述

Some people think that the bigger an elephant is, the smarter it is. To disprove this, you want to take
the data on a collection of elephants and put as large a subset of this data as possible into a sequence
so that the weights are increasing, but the IQ’s are decreasing.
Input
The input will consist of data for a bunch of elephants, one elephant per line, terminated by the end-
of-file. The data for a particular elephant will consist of a pair of integers: the first representing its size
in kilograms and the second representing its IQ in hundredths of IQ points. Both integers are between
1 and 10000. The data will contain information for at most 1000 elephants. Two elephants may have
the same weight, the same IQ, or even the same weight and IQ.
Output
Say that the numbers on the i-th data line are W[i] and S[i]. Your program should output a sequence
of lines of data; the first line should contain a number n; the remaining n lines should each contain
a single positive integer (each one representing an elephant). If these n integers are a[1], a[2],…, a[n]
then it must be the case that
W[a[1]] < W[a[2]] < … < W[a[n]]
and
S[a[1]] > S[a[2]] > … > S[a[n]]
In order for the answer to be correct, n should be as large as possible. All inequalities are strict:
weights must be strictly increasing, and IQs must be strictly decreasing.
There may be many correct outputs for a given input, your program only needs to find one.
Sample Input
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900
Sample Output
4
4
5
9
7

简单说下这题

这道题目很明显是LIS的改编,那么这道题目怎么写呢?这道题目大概就是叫你求出一个规律,体重越大智商越低。这道题目我们可以先对智商排序,然后对体重用LIS来求出。这题题目本身不难,有点难的地方(其实是我的知识盲区,开始不懂这个)就是路径的输出,在网上blog看了下,对于LIS本身而已,我所用的nlogn的算法所求出来的路径并不是正确的路径,但是求出的长度是正确的(开始一直WA,想了下是这个原因,对这方面不是很熟悉是原罪)。
对于LIS,n
logn的算法,用的是倒序输出。首先用一个数组pos记录下每个dp过程中数在dp数组中的位置。然后对原数组倒序遍历,找出每个位置(dp数组)对应的第一个出现的位置(原数组)并记录下来,正序输出即是答案。
这个倒序输出的思想,我认为是利用了贪心,因为dp的时候,每个位置对应的记录的数一直在变,一直在记录潜力较大的数,相当于天然记录了每个数的潜力大小,所以我们只需要利用这个,记录每个数出现在dp数组中的对应位置,然后倒序存储路径(从后面的位置开始是为了后数不受先数影响),每次选出最优的数的位置,最后得到的就是答案了。

#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
typedef struct
{
    int w;
    int s;
    int local;
} node;
node a[1005],c[1005];
int pos[1005],ans[1005];
int len=1,maxlen=0;
bool cmp(node x,node y)
{
    return x.s>=y.s;
}
int bs(int key)
{
    int mid,x=1,y=maxlen;
    while(x<=y)
    {
        mid=(x+y)>>1;
        if(c[mid].w<key)
            x=mid+1;
        else
            y=mid-1;
    }
    return x;
}
int main()
{
    while(scanf("%d%d",&a[len].w,&a[len].s)!=EOF)
    {
        a[len].local=len;
        len++;
    }
    sort(a+1,a+len,cmp);
    for(int i=1; i<len; i++)
    {
        int k;
        k=bs(a[i].w);
        pos[i]=k;
        c[k]=a[i];
        maxlen=max(k,maxlen);
    }
    cout<<maxlen<<endl;
    int t=maxlen;
for(int i=len-1;i>0;i--){
    if(pos[i]==t){
        ans[t--] = a[i].local;//获得正确路径
    }
    if(maxlen<1) break;
}
for(int i=1;i<=maxlen;i++)
    cout<<ans[i]<<endl;
    return 0;
}
发布了43 篇原创文章 · 获赞 26 · 访问量 3090

猜你喜欢

转载自blog.csdn.net/Leo_zehualuo/article/details/104377074