CF EDU 120 E - Math Test

E - Math Test

拆绝对值

要求 i=1n|rixi| 的最大值,可以将绝对值拆开,对于每一个 i,若 ri>=xi, 设 sgn[i]=1. 否则设为 sgn[i]=1i=1n|rixi|=i=1nsgn[i]risgn[i]xi

由于 n 很小,可枚举这 2n 种符号,此时 i=1nsgn[i]x[i] 已经固定,只需求 i=1nsgn[i]r[i] 的最大值,r[i]=j=1mp[j](s[i][j]==1), 因此 i=1nsgn[i]r[i]=j=1mp[j]i=1nsgn[i](s[i][j]==1)

所以贪心的对于最小的 i=1nsgn[i](s[i][j]==1) 这道题的分值就给 1,第二小的给 2 ...

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 11, M = 1e4 + 10;
ll x[N], p[M];
int sgn[N];
int n, m;
string str[N];

int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n >> m;
		for (int i = 0; i < n; i++)
			cin >> x[i];
		for (int i = 0; i < n; i++)
			cin >> str[i];
		for (int i = 0; i < m; i++)
			p[i] = i + 1;
		ll ans = 0;
		for (int s = 0; s < 1 << n; s++)
		{
			for (int i = 0; i < n; i++)
			{
				if (s >> i & 1)
					sgn[i] = 1;
				else
					sgn[i] = -1;
			}
			vector<PII> vt;
			for (int j = 0; j < m; j++)
			{
				int t = 0;
				for (int i = 0; i < n; i++)
					t += sgn[i] * (str[i][j] == '1');
				vt.push_back({t, j});
			}
			sort(vt.begin(), vt.end());
			ll now = 0;
			for (int i = 0; i < m; i++)
				now += (i + 1) * vt[i].first;
			for (int i = 0; i < n; i++)
				now -= sgn[i] * x[i];
			if (now > ans)
			{
				ans = now;
				for (int i = 0; i < m; i++)
					p[vt[i].second] = i + 1;
			}
		}
		for (int i = 0; i < m; i++)
			cout << p[i] << " ";
		cout << endl;
	}
	return 0;
}

posted @   hzy0227  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示