《编程思维与实践》1031.最小向量点积

《编程思维与实践》1031.最小向量点积

题目

在这里插入图片描述
在这里插入图片描述

思路

注意到题目中给出的具体例子中,只需要将两个向量的分量分别升序和降序排列后再求点积就可以得到最小值,

为了严谨起见,下面给出该方法数学依据(排序不等式)的证明:

数学归纳法:
对 k 进行归纳 : 当 k = 1 时 , 不等式显然成立 . 下设 k = n − 1 时不等式成立 , 探讨 k = n 时的情形 : 由归纳假设 : ∑ i = 1 n − 1 a i b n + 1 − i ≤ ∑ i = 1 n − 1 a i b j i ≤ ∑ i = 1 n − 1 a i b i 对于右端有 ∑ i = 1 n a i b i = ∑ i = 1 n − 1 a i b i + a n b n ≥ ∑ i = 1 n − 1 a i b j i + a n b n 又由于将 n 依此与 1 到 n − 1 的全排列 j 1 j 2 . . . j n − 1 中的某个数调换 ( 等价于插空位 ) 即可得到 1 到 n 的全排列 j 1 j 2 . . . j n , 设 b n 与 b j m ( m ≤ n − 1 ) 进行调换 , 由于 a n b j m + a m b n ≤ a n b n + a m b j m , 即 ( a n − a m ) ( b n − b j m ) ≥ 0 ( 由 a n , b n 升序排列可知不等式成立 ) 所以 ∑ i = 1 n a i b i ≥ ∑ i = 1 n − 1 a i b j i + a n b n ≥ ∑ i = 1 n a i b j i 同理对于左端有 ∑ i = 1 n a i b n + 1 − i = ∑ i = 1 n − 1 a i b n + 1 − i + a n b 1 ≤ ∑ i = 1 n − 1 a i b j i + a n b 1 将 1 依此与 2 到 n 的全排列调换 , 设 b 1 与 b t 调换 , 有 a n b j t + a t b 1 ≥ a n b 1 + a t b j t , 即 ( a n − a t ) ( b j t − b 1 ) ≥ 0 , 显然成立 . 对k进行归纳:当k=1时,不等式显然成立. \\ 下设k=n-1时不等式成立,探讨k=n时的情形:\\ 由归纳假设:\sum_{i=1}^{n-1}a_ib_{n+1-i}≤\sum_{i=1}^{n-1}a_ib_{j_i}≤\sum_{i=1}^{n-1}a_ib_i \\ 对于右端有\sum_{i=1}^{n}a_ib_i=\sum_{i=1}^{n-1}a_ib_i+a_nb_n≥\sum_{i=1}^{n-1}a_ib_{j_i}+a_nb_n \\ 又由于将n依此与1到n-1的全排列j_1j_2...j_{n-1}中的某个数调换(等价于插空位)即可得到1到n的全排列j_1j_2...j_n,\\ 设b_n与b_{j_m}(m≤n-1)进行调换,由于a_nb_{j_m}+a_mb_n≤a_nb_n+a_mb_{j_m},\\ 即(a_n-a_m)(b_n-b_{j_m})≥0(由a_n,b_n升序排列可知不等式成立)\\ 所以\sum_{i=1}^{n}a_ib_i≥\sum_{i=1}^{n-1}a_ib_{j_i}+a_nb_n≥\sum_{i=1}^{n}a_ib_{j_i}\\ 同理对于左端有\sum_{i=1}^{n}a_ib_{n+1-i}=\sum_{i=1}^{n-1}a_ib_{n+1-i}+a_nb_1≤\sum_{i=1}^{n-1}a_ib_{j_i}+a_nb_1 \\ 将1依此与2到n的全排列调换,设b_1与b_t调换,有a_nb_{j_t}+a_tb_1≥a_nb_1+a_tb_{j_t},\\ 即(a_n-a_t)(b_{j_t}-b_1)≥0,显然成立. k进行归纳:k1,不等式显然成立.下设k=n1时不等式成立,探讨k=n时的情形:由归纳假设:i=1n1aibn+1ii=1n1aibjii=1n1aibi对于右端有i=1naibi=i=1n1aibi+anbni=1n1aibji+anbn又由于将n依此与1n1的全排列j1j2...jn1中的某个数调换(等价于插空位)即可得到1n的全排列j1j2...jn,bnbjm(mn1)进行调换,由于anbjm+ambnanbn+ambjm,(anam)(bnbjm)0(an,bn升序排列可知不等式成立)所以i=1naibii=1n1aibji+anbni=1naibji同理对于左端有i=1naibn+1i=i=1n1aibn+1i+anb1i=1n1aibji+anb11依此与2n的全排列调换,b1bt调换,anbjt+atb1anb1+atbjt,(anat)(bjtb1)0,显然成立.

代码

#include<stdio.h>
#include<stdlib.h>

int cmp1(const void *a,const void *b) //从小到大 
{
    
    
	int *m=(int*)a;
	int *n=(int*)b;
	return *m-*n;
}

int cmp2(const void *a,const void *b) //从大到小 
{
    
    
	int *m=(int*)a;
	int *n=(int*)b;
	return *n-*m;
}

int main()
{
    
    
	int T;
	scanf("%d",&T);
	for(int i=0;i<T;i++)
	{
    
    
		int n;
		scanf("%d",&n);
		int vector1[n],vector2[n];
		for(int j=0;j<n;j++)
		{
    
    
			scanf("%d",&vector1[j]);
		}
		for(int j=0;j<n;j++)
		{
    
    
			scanf("%d",&vector2[j]);
		}
		qsort(vector1,n,sizeof(int),cmp1);
		qsort(vector2,n,sizeof(int),cmp2);
		long long count=0;
		for(int j=0;j<n;j++)
		{
    
    
			count+=vector1[j]*vector2[j];
		} 
		printf("case #%d:\n",i);
		printf("%lld\n",count);
	}
 } 

猜你喜欢

转载自blog.csdn.net/boxueyuki/article/details/130029643