[Violet 2]After 17 題解

題目大意爲給出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;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章