|
楼主 |
发表于 2006-7-31 01:08:32
|
显示全部楼层
Post by Lolita
事实上要求的P只有S中最大的前n个元素,那么可以证明构成P中的任一元素的值Val(ab)必定满足:a=A[0] 或者 b=B[0],基于这个事实,可以用下述算法求P。时间复杂度是O(n)。为了易于描述,主要增设了两个队列数组保存差值,然后通过差值大小来确定P的每个输出值。
- #include <stdio.h>
- /* 计算A[i](i=1,2,3,...,n-1)与A[0]的差值,adjust用来对差值进行调校 */
- void get_offset(int A[], int offset[], const int n, int adjust)
- {
- int i=1;
- offset[0]=0;
- while(i<n)
- {
- offset[i]=A[i]-A[0]+adjust;
- ++i;
- }
- }
- /* 通过A、B各自的offset值计算P */
- void getp(int A[], int B[], int P[], const int n)
- {
- if(n<1)return; /* n必须大于1 */
-
- int i;
- int A_offset[n],B_offset[n];
- int pa,pb; /* 分别指向A_offset和B_offset的索引指针 */
-
- get_offset(A,A_offset,n,0);
- get_offset(B,B_offset,n,A[0]-B[0]);
-
- P[0]=A[0]+B[0]; /*这个最大,无可非议*/
-
- i=1;
- pa=pb=1;
- while(i<n)
- {
- /* 或用一行语句 P[i++]= A_offset[pa]>B_offset[pb] ? (B[0]+A[pa++]) : (A[0]+B[pb++]); */
- if(A_offset[pa]>B_offset[pb])
- {
- P[i]=B[0]+A[pa];
- ++pa;
- }
- else
- {
- P[i]=A[0]+B[pb];
- ++pb;
- }
- ++i;
- }
- }
- int main()
- {
- const int n=5;
- int A[]={100,99,98,96,40,1};
- int B[]={99,20,10,5,4,3};
- //int A[]={100,99,98,40,20};
- //int B[]={99,60,40,30,28};
- int P[n];
- getp(A,B,P,n);
- int i;
- for(i=0;i<n;i++)printf("%d\n",P[i]);
-
- }
复制代码
输出:
恩,思路是蛮好的,可是仍旧没有解决问题。我构造了一个较为复杂一点的数列来应证我的算法,这里可以改出供大家参考。
A[] = (20,19,15,10,9,7,5,4,3,1)
B[]= (18,17,15,14,11,10,8,7,6,4)
问题:1. 正如ak70所说,off_set相等的情况没有考虑。2. 更为复杂的情况是在下轮,下下轮,等的比较中可能出现比前面大的值。这个要在一次排序中调整,个人感觉难度很大。 我是觉得由于数列的组合值不太有规律性,O(n)的可能性似乎不大。 |
|