排兵布阵(写题过程)

题目描述

小 C 正在玩一款排兵布阵的游戏。在游戏中有 nn 座城堡,每局对战由两名玩家来争夺这些城堡。每名玩家有 mm 名士兵,可以向第 ii 座城堡派遣 a_iai​ 名士兵去争夺这个城堡,使得总士兵数不超过 mm。

如果一名玩家向第 ii 座城堡派遣的士兵数严格大于对手派遣士兵数的两倍,那么这名玩家就占领了这座城堡,获得 ii 分。

现在小 C 即将和其他 ss 名玩家两两对战,这 ss 场对决的派遣士兵方案必须相同。小 C 通过某些途径得知了其他 ss 名玩家即将使用的策略,他想知道他应该使用什么策略来最大化自己的总分。

由于答案可能不唯一,你只需要输出小 C 总分的最大值。

输入格式

输入第一行包含三个正整数 s,n,ms,n,m,分别表示除了小 C 以外的玩家人数、城堡数和每名玩家拥有的士兵数。

接下来 ss 行,每行 nn 个非负整数,表示一名玩家的策略,其中第 ii 个数 a_iai​ 表示这名玩家向第 ii 座城堡派遣的士兵数。

输出格式

输出一行一个非负整数,表示小 C 获得的最大得分。

样例 1

InputcopyOutputcopy
1 3 10
2 2 6
3

小 C 的最佳策略为向第 11 座城堡和第 22 座城堡各派遣 55 名士兵。

样例 2

InputcopyOutputcopy
2 3 10
2 2 6
0 0 0
8

小 C 的最佳策略之一为向第 11 座城堡派遣 22 名士兵,向第 22 座城堡派遣 55 名士兵,向第 33 座城堡派遣 11 名士兵。

100% 的数据,保证

  • 1001≤s≤100
  • 1001≤n≤100
  •  2\times 10^41≤m≤2×104
  • 对于每名玩家,a_i \ge 0, \sum\limits_{i=1}^n a_i \le mai​≥0,i=1∑n​ai​≤m。
#include<cstring>
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<map>
#include<cmath>
//#include<unordered_map>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<stdlib.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 11;
ll s, n, m;
ll v[8] = { 1,5,10,25,50 };
//ll w[N];
ll bag[N];
ll peo[150][N];
//int six[N];
//struct node
//{
//	int v,w;
//};
int main()
{
	cin >> s >> n >> m;//s玩家人数,n城堡,m兵数
	for (int i = 1;i <= s;i++)
	{
		for (int j = 1;j <= n;j++)
		{
			cin >> peo[j][i];//记录第i个玩家对第j个城堡的出兵数量
		}
	}
	for (int i = 1;i <= n;i++)
	{
		sort(peo[i] + 1, peo[i] + 1 + s);//排序,将第i坐城堡的每个玩家对其出兵数量进行排序;;个人感觉其实不排序也是可以的
	}
	for (int i = 1;i <= n;i++)//开始遍历城堡
	{
		for (int j = m;j >= 1;j--)//
		{//这里的j代表着小明对第i城堡出兵数量
			for (int k = 1;k <= s;k++)//遍历每个玩家对第i个城堡出兵数
			{
				if (j > 2 * peo[i][k])bag[j] = max(bag[j], bag[j - 2 * peo[i][k] - 1] + k * i);//题目说当小明出兵数量大于其他玩家出兵数俩倍的时候获得i分,因此j > 2 * peo[i][k]才能更改bag里面的数值
/为什么还要再减去1,就类似于数学里面算日期之类的问题类似,然后为什么k*i:第i个玩家比的出兵数量必然是大于等于前面的数值(因为排序了)所以,当第k个玩家小明打得过,那么前面的玩家都是打的过的分数小明都能得到;
			}
		}
	}
	cout << bag[m];
	return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值