题目描述 Description
世界上的人都有智商IQ和情商EQ。我们用两个数字来表示人的智商和情商,数字大就代表其相应智商或情商高。现在你面前有N个人,这N个人的智商和情商均已知,请你选择出尽量多的人,要求选出的人中不存在任意两人i和j,i的智商大于j的智商但i的情商小于j的情商。
输入描述 Input Description
第一行一个正整数N,表示人的数量。 第二行至第N+1行,每行两个正整数,分别表示每个人的智商和情商。
输出描述 Output Description
仅一行,为最多选出的人的个数。
样例输入 Sample Input
3 100 100 120 90 110 80
样例输出 Sample Output
2
数据范围及提示 Data Size & Hint
N<=1000;
u�� A�z%ೀ%过程为一次一次的购买,每一次购买也许只买一本(这有三种方案),或者买两本(这也有三种方案),或者三本一起买(这有一种方案),最后直到买完所有需要的书。
2、最后一步我必然会在7种购买方案中选择一种,因此我要在7种购买方案中选择一个最佳情况。
3、子问题是,我选择了某个方案后,如何使得购买剩余的书能用最少的钱?并且这个选择不会使得剩余的书为负数。母问题和子问题都是给定三卷书的购买量,求最少需要用的钱,所以有“子问题重叠”,问题中三个购买量设置为参数,分别为i、j、k。
4、的确符合。
5、边界是一次购买就可以买完所有的书,处理方式请读者自己考虑。
6、每次选择最多有7种方案,并且不会同时实施其中多种,因此方案的选择互不影响,所以有“子问题独立”。
7、我可以用minMoney[i][j][k]来保存购买第1卷i本,第2卷j本,第3卷k本时所需的最少金钱。
8、共有x * y * z 个问题,每个问题面对7种选择,时间为:O( x * y * z * 7) = O( x * y * z )。
9、用函数MinMoney(i,j,k)来表示购买第1卷i本,第2卷j本,第3卷k本时所需的最少金钱,那么有:
MinMoney(i,j,k)=min(s1,s2,s3,s4,s5,s6,s7),其中s1,s2,s3,s4,s5,s6,s7分别为对应的7种方案使用的最少金钱:
s1 = 60 * 0.95 + MinMoney(i-1,j,k)
s2 = 60 * 0.95 + MinMoney(i,j-1,k)
s3 = 60 * 0.95 + MinMoney(i,j,k-1)
s4 = (60 + 60) * 0.9 + MinMoney(i-1,j-1,k)
s5 = (60 + 60) * 0.9 + MinMoney(i-1,j,k-1)
s6 = (60 + 60) * 0.9 + MinMoney(i-1,j,k-1)
s7 = (60 + 60 + 60) * 0.85 + MinMoney(i-1,j-1,k-1)
----第六节----代码参考------
下面提供金矿问题的程序源代码帮助读者理解,并提供测试数据给大家练习。
输入文件名为“beibao.in”,因为这个问题实际上就是背包问题,所以测试数据文件名就保留原名吧。
输入文件第一行有两个数,第一个是国王可用用来开采金矿的总人数,第二个是总共发现的金矿数。
输入文件的第2至n+1行每行有两个数,第i行的两个数分别表示第i-1个金矿需要的人数和可以得到的金子数。
输出文件仅一个整数,表示能够得到的最大金子数。
输入样例:
100 5
77 92
22 22
29 87
50 46
99 90
输出样例:
133
var iq,eq:array[1..100]of longint; f:array[1..100] of longint; n,i1:longint; function max(a,b:longint):longint; begin if a>b then exit(a) else exit(b); end; procedure qsort(l,r:longint); var i,j,mid,t:longint; begin i:=l; j:=r; mid:=iq[(i+j)div 2]; repeat while iq[i]<mid do inc(i); while iq[j]>mid do dec(j); if i<=j then begin t:=iq[i]; iq[i]:=iq[j]; iq[j]:=t; t:=eq[i]; eq[i]:=eq[j]; eq[j]:=t; inc(i); dec(j); end; until i>j; if l<j then qsort(l,j); if r>i then qsort(i,r); end; {快速排序} procedure main; var i,j,t:longint; begin t:=0; f[1]:=1; for i:=2 to n do begin for j:=1 to i-1 do if (eq[j]<eq[i])and(f[j]>f[i])then f[i]:=f[j]; inc(f[i]); end; for i:=1 to n do t:=max(t,f[i]); writeln(t); end; begin fillchar(f,sizeof(f),0); read(n); for i1:=1 to n do read(iq[i1],eq[i1]); qsort(1,n); main; end. {需要用双重关键字排序,先为一个排序后再求另一个严格上升子序列}