描述
今天是Cheer 的17 岁生日,而她17 岁这年最大的梦想就是出去远行。为此,她打算制定 n 条旅行线路。
为了简化起见,我们把这个世界想象成一个平面直角坐标系,而Cheer 所在的小镇则为原点。由于父亲不让Cheer 走得太远,她每次旅行的目的地都被限制在一个对应的右上角为(x, y),左下角为(-x,-y)的矩形内。
每次 Cheer 都会从原点直接沿直线走到目的地。显然,她走过了一个向量,这被数学控的Cheer 称为这次的旅行向量。Cheer 为了更好地规划旅行线路,为每条旅行线路定义了一个无聊值,即这次的旅行向量和其余所有之前的线路的旅行向量的点积和。
Cheer 希望合理的选择目的地,使得所有旅行线路的无聊值之和最小。
输入
第一行一个正整数n ,表示Cheer 打算制定n 条旅行线路。
接下来 n 行,每行两个整数x , y ,描述一个限制目的地的矩形。
输出
一行一个整数,即最小的无聊值,保留 2 位小数。
输入样例 1
2 1 2 2 1
输出样例 1
-4.00
提示
对于 10% 的数据,保证 0<n,x,y≤5
对于 30% 的数据,保证0<n,≤20,0<x,y≤100
对于 100% 的数据,保证0<n,≤200 ,0<x,y≤200
#include <bits/stdc++.h>
using namespace std;
inline const long long getint()
{
long long w=0, k=1;
char q=getchar();
for(; q<'0'||q>'9'; q=getchar())
if(q=='-')
k=-1;
for(; q>='0'&&q<='9'; q=getchar())
w=w*10+q-'0'; return w*k;
}
inline const int max(const int &a, const int &b)
{
return a>b?a:b;
}
inline const int min(const int &a, const int &b)
{
return a<b?a:b;
}
const int N=400;
int x[N], y[N], n, ans;
bool d[2][N*N*2];
int dp(int *a)
{
int sum=0, S=N*N, pos=0;
memset(d, 0, sizeof(d));
d[pos^1][S]=1;
for(int i=(1); i<=(n); ++i)
{
for(int j=(S-sum-a[i]); j<=(S+sum+a[i]); ++j)
d[pos][j]=0;
for(int j=(S-sum-a[i]); j<=(S+sum+a[i]); ++j)
if(d[pos^1][j])
d[pos][j+a[i]]=1, d[pos][j-a[i]]=1;
sum+=a[i];
pos^=1;
}
pos=1;
int mn=~0u>>1;
for(int i=(S); i<=(S+sum); ++i)
if(d[pos][i])
{
mn=min(mn, i-S);
break;
}
for(int i=(S); i>=(S-sum); --i)
if(d[pos][i])
{
mn=min(mn, S-i);
break;
}
return mn*mn;
}
int main() {
float ans;
n=getint();
for(int i=(1); i<=(n); ++i)
x[i]=getint(), y[i]=getint();
for(int i=(1); i<=(n); ++i)
ans-=x[i]*x[i];
for(int i=(1); i<=(n); ++i)
ans-=y[i]*y[i];
ans+=dp(x);
ans+=dp(y);
cout << fixed << setprecision(2) << ans / 2;
return 0;
}
AC了qwq