【状态压缩 && 数学】ZOJ - 3280 Choose The Best

Step1 Problem:

给你n个,m维的点。
求最远的带权值的曼哈顿距离
数据范围:
2<=n<=50000, 1 <= m <= 8.

Step2 Involving algorithms:

状态压缩 && 数学

Step3 Ideas:

K-D树应该可以做,但是我们要说的是另一种方法。
把权值乘进去,题目相当于就是求最远的曼哈顿距离。
对于1维:|x1 - x2| = x1 - x2 or -x1 - (-x2)
对于2维:|x1 - x2| + |y1 - y2| = (x1+y1) - (x2 + y2) or (x1-y1) - (x2 - y2) or (-x1+y1) - (-x2 + y2) or (-x1-y1) - (-x2 - y2)
对于n维:正号为1,负号为0的话。也就是2^n个状态求最大。

Step4 Code:

#include<bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int a[50005][10];
int w[10];
int main()
{
    int n, m;
    while(~scanf("%d %d", &n, &m))
    {
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
                scanf("%d", &a[i][j]);
        }
        for(int i = 0; i < m; i++)
            scanf("%d", &w[i]);
        int ans = 0;
        for(int k = 0; k < (1<<m); k++)
        {
            int Min = inf, Max = -inf;
            for(int i = 0; i < n; i++)//对于每个状态 更新最大。
            {
                int tmp = 0;
                for(int j = 0; j < m; j++)
                {
                    if(k&(1<<j)) tmp += a[i][j] *w[j];
                    else tmp -= a[i][j]*w[j];
                }
                Min = min(tmp, Min);
                Max = max(tmp, Max);
                ans = max(ans, Max-Min);
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值