编程题-最小向量内积-(1)

有两个向量v1=(x1,x2,...,xn)和v2=(y1,y2,...,yn),允许任意交换v1和v2各自的分量的顺序,计算v1和v2的内积x1y1+x2y2+...+xnyn的最小值

样例:

输入:

n=3

v1=(1,3,?5)

v2=(?2,4,1)

输出:

-25

( 令v1=(?5,1,3),v2=(4,1,?2) )

首先我第一感觉就是,要保证最小,

1.如果在有正有负的情况下,那么有最大的正数乘以最小的负数,

2.如果都是正数,用最大的正数乘以最小的正数,

3.如果都是负数,用最大的负数数乘以最小的负数,

其实以上的3个条件就是两个向量分别按照升序和降序排列,得到的内积最小

按照上面的方法,不断的从v1和v2取出配对的量,最后得出的结果可能是最优的结果。

举个样例试一试

v1=(x1,x2) ,v2=(y1,y2)

如果v1已经是按照升序排列,即x1≤x2,比较 x1×y1+x2×y2 和x1×y2+x2×y1的大小

(x1×y1+x2×y2)?(x1×y2+x2×y1)

=(x1(y1?y2)+x2(y2?y1))

=(x1?x2)(y1?y2)

可以看出,如果y1<y2,即x1×y1+x2×y2>x1×y2+x2×y1

意味着,我们可以通过交换y1和y2的位置得到一个更小的向量内积值

延伸到 n>2

我们也同样把V1按照升序排列,对于v2如果存在 i<j,并且yi<yj我们可以通过交换yi和yj的位置,得到一个更小的例子

x1y1+...+xiyi+...+xjyj+...+xnyn>x1y1+...+xiyj+...+xjyi+...+xnyn

#include <iostream>
#include <algorithm>

using namespace std;
int compare(int a,int b)
{
    return a>b;
}
int main()
{
    int n,i;
    cout<<"input n: ";
    cin>>n;
    cout<<endl;
    cout<<"input v1 :"<<endl;
    int *v1=new int[n];
    int *v2=new int[n];
    for(i=0;i<n;i++)
    {
        cin>>v1[i];
    }
    cout<<"input v2 :"<<endl;
    for(i=0;i<n;i++)
    {
        cin>>v2[i];
    }
    //v1 升序
    sort(v1,v1+n);
    //v2 降序
    sort(v2,v2+n,compare);
    int min=0;
    for(i=0;i<n;i++){
        min+=v1[i]*v2[i];
    }
    cout<<"minimum is :"<<min<<endl;
    delete [] v1;
    delete [] v2;
    return 0;
}
input n: 3

input v1 :
1 3 -5
input v1 :
-2 4 1
minimum is :-25
时间: 2024-10-21 10:14:07

编程题-最小向量内积-(1)的相关文章

[BZOJ]3243 向量内积(Noi2016)

小C做了之后很有感觉的题目之一,但因为姿势不对调了很久. Description 两个d 维向量A=[a1,a2,...,ad]与B=[b1,b2,...,bd]的内积为其相对应维度的权值的乘积和,即: 现有 n 个d 维向量x1,...,xn ,小喵喵想知道是否存在两个向量的内积为k的倍数.请帮助她解决这个问题. Input 第一行包含3个正整数n,d,k,分别表示向量的个数,维数以及待检测的倍数.接下来n行每行有d个非负整数,其中第i行的第j个整数表示向量xi的第j维权值xi,j. N<=1

[编程题-蘑菇街] 最大间隔

[编程题] 最大间隔 给定一个递增序列,a1 <a2 <...<an .定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤i<n),现在要从a2 ,a3 ..an-1 中删除一个元素.问剩余序列的最大间隔最小是多少? 输入描述: 第一行,一个正整数n(1<=n<=100),序列长度;接下来n个小于1000的正整数,表示一个递增序列. 输出描述: 输出答案. 输入例子: 51 2 3 7 8 输出例子: 4 #include<iostream>

POJ C程序设计进阶 编程题#4:寻找平面上的极大点

编程题#4:寻找平面上的极大点 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 在一个平面上,如果有两个点(x,y),(a,b),如果说(x,y)支配了(a,b),这是指x>=a,y>=b; 用图形来看就是(a,b)坐落在以(x,y)为右上角的一个无限的区域内. 给定n个点的集合,一定存在若干个点,它们不会被集合中的任何一点所支配,这些点叫做极大值点. 编程找出所有的极大

POJ C程序设计进阶 编程题#2:四大湖

编程题#2:四大湖 来源: POJ(Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 我国有4大淡水湖. A说:洞庭湖最大,洪泽湖最小,鄱阳湖第三. B说:洪泽湖最大,洞庭湖最小,鄱阳湖第二,太湖第三. C说:洪泽湖最小,洞庭湖第三. D说:鄱阳湖最大,太湖最小,洪泽湖第二,洞庭湖第三. 已知这4个湖的大小均不相等,4个人每人仅答对一个, 请编程按照鄱阳湖.洞庭湖.太湖.洪泽湖的顺序给出他们的

问题 1065: 2004年秋浙江省计算机等级考试二级C 编程题(1)

/******************************************************************** @file Main.cpp @date 2017-6-28 10:45:08 @author Zoro_Tiger @brief 问题 1065: 2004年秋浙江省计算机等级考试二级C 编程题(1) http://www.dotcpp.com/oj/problem1065.html ************************************

上机操作编程题

一.写一个简单的缓存系统 1 package com.wisezone.demo; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 /** 6 * 上机操作: 7 * 面试题--写一个简单的缓存系统 8 * @author 王东海 9 * @2017年6月5日 10 */ 11 public class CacheDemo 12 { 13 private Map<String, Object> map = new HashMap&

蘑菇街2016研发工程师在线编程题

传送门 第一题: [编程题] 搬圆桌 现在有一张半径为r的圆桌,其中心位于(x,y),现在他想把圆桌的中心移到(x1,y1).每次移动一步,都必须在圆桌边缘固定一个点然后将圆桌绕这个点旋转.问最少需要移动几步. 输入描述: 一行五个整数r,x,y,x1,y1(1≤r≤100000,-100000≤x,y,x1,y1≤100000) 输出描述: 输出一个整数,表示答案 输入例子: 2 0 0 0 4 输出例子: 1 题解转自:ixiaomo 思路很简单,千万别想复杂了 无论圆桌如何移动,都必须在圆

POJ C程序设计进阶 编程题#3 : 排队游戏

编程题#3:排队游戏 来源: POJ (Coursera声明:在POJ上完成的习题将不会计入Coursera的最后成绩.) 注意: 总时间限制: 1000ms 内存限制: 65536kB 描述 在幼儿园中,老师安排小朋友做一个排队的游戏.首先老师精心的把数目相同的小男孩和小女孩编排在一个队列中,每个小孩按其在队列中的位置发给一个编号(编 号从0开始).然后老师告诉小朋友们,站在前边的小男孩可以和他后边相邻的小女孩手拉手离开队列,剩余的小朋友重新站拢,再按前后相邻的小男孩小女孩手拉 手离开队列游戏

笔试:编程题

0,1背包问题: 定义V(i,j):当前背包容量 j,前 i 个物品最佳组合对应的价值: 递推关系式: 1) j<w(i)      V(i,j)=V(i-1,j) 2) j>=w(i)     V(i,j)=max{ V(i-1,j),V(i-1,j-w(i))+v(i) } 参考:动态规划-01背包问题 网易2017春招笔试编程题集合: 双核处理: 两个CPU,多个任务:求最小时间: 输入: 5 3072 3072 7168 3072 1024 输出: 9216 解法: 动态规划问题:以总