[Violet 2]After 17 题解

来源:互联网 发布:圆弧插补算法 螺旋线 编辑:程序博客网 时间:2024/06/07 00:53

题目大意为给出n个矩形,求出一个向量,每个向量都不超越各自的矩形。求最小化sigma(xi * xj+yi*yj) i<j 点积



x和y坐标可以分开来考虑

首先sigma(xi* xj) (i<j) = ((x1+....+xn)^2- (x1*x1+...+xn*xn))/2      向量的值一定取在各自的边界上,所以x1*x1+...........+xn*xn 是定值。

目前就是最小化 x1+....+xn的绝对值,经典的背包问题。



#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;const int MAXM = 40000;int f[200+10][MAXM*2+10];int n,x[200+10],y[200+10],a[200+10];int ans;void     work(){   for (int i = 0; i <= n; ++i)       for (int j = -MAXM; j <= MAXM; ++j)           f[i][j+MAXM] = false;          f[0][0+MAXM]=true;   for (int i = 1; i <= n;++i)       for (int j = -MAXM; j <= MAXM; ++j)       if  (f[i-1][j+MAXM]) f[i][j-a[i]+MAXM]=f[i][j+a[i]+MAXM]=true;          for (int i = 0; i <= MAXM; ++i)   if (f[n][i+MAXM]) { ans+=i*i ; return ;}}int main(){    cin>>n; ans = 0;    for (int i = 1; i <= n ; ++i)    {         scanf("%d %d", &x[i], &y[i]);         ans -= (x[i]*x[i]+y[i]*y[i]);         a[i] = x[i];    }    work();    for (int i = 1; i <= n ; ++i)        a[i] = y[i];    work();    cout << ans/2<<".00"<< endl;    return 0;}



原创粉丝点击