Problem J. CSGO(K维曼哈顿最大距离+二进制状态压缩(或者叫枚举二进制))

在这里插入图片描述
在这里插入图片描述
这道题,如果读懂了题意,就应该知道这里的Sample Input格式有问题;但是不影响分析;
首先我觉得很多人肯定会想到,枚举,根据题目的公式找出MW里面的最大值,然后找出SW中的最大值;就可以解决了,但是我当时始终不知道枚举,我想了一种但是1e5*1e5肯定爆;
所以这个方法行不通;之后我去百度了一下这个题,我才知道,这原来是曼哈顿最远距离的变形题;
首先应该知道什么是曼哈顿距离:比如在二维坐标中的定义:d(i,j)=|xi-xj|+|yi-yj|;在几何意义上就是:
在这里插入图片描述
这就是曼哈顿距离;但是怎么解决多维的曼哈顿距离呢?
首先解决什么是多维:
我们二维坐标是不是(xi,yi)?三位坐标是不是(xi,yi,zi)?;那么多维我们就可以用代数形式表示为:
(x1,x2,x3,x4…xn);这就是多维上的坐标形式,只是这里的y,z写成了x2,x3的形式,所它们的本质是一样滴;(注意这里是n维的一个点)
那么这道题的后面这一坨:在这里插入图片描述
不就是k维的曼哈顿距离吗?因为对于主武器Swm对应一个k维的点;所以我们在枚举的时候只需要让它们在逻辑上产生联系(其实用一个结构体就OK了或者再开别的数组);
那么怎么计算k维最大的曼哈顿距离呢?
想来看这个:我可以知道,对于二维的曼哈顿定义形式,如:
d(1,2)=|x1-x2|+|y1-y2|;可以经过下面四种讨论,我就可以把绝对值去掉:
1.如果x1-x2为正 && y1-y2为正数 那么d(1,2)=x1-x2+y1-y2;
2.如果x1-x2为正&& y1-y2为负数 那么d(1,2)=x1-x2+y2-y1;
3.如果x1-x2为负&&y1-y2为正数 那么d(1,2)=x2-x1+y1-y2;
4.如果x1-x2为负&&y-1-y2为负数 那么d(1,2)=x2-x1+y2-y1;
那么二维上的两个点之间的曼哈顿距离就只有这四种形式:
然后我们把x1和y1放在一起,x2和y2放在一起可以知道d(1,2)有下面四种取值形式:
在这里插入图片描述
但是哪一个最大呢?当然枚举去判断咯;
上面的形式可以发现x1和x2的系数都是相同的(+,-好都一样),同理可知:y1和y2的也是一样的;
这点说明了什么呢?说明我可以用0表示负号,1表示正号,也就是说:
在这里插入图片描述
可以发现都是从00—11的,然后来枚举每种状态,因为两个的点的x,y对应的状态都是相同的;
那么多维就可以类比思考;
好了,到这里这道题就解决了一大半了;
那么怎么枚举状态呢?其实如果写过用位运算求子集的应该可以想到用两个for就可以枚举出所有的状态;
这样就把本属于类的枚举转化为了一类中自己的枚举了;这样时间复杂度就成了O(2n)了;
AC代码(只不过这道题换成了n+m个k维的点了,每次枚举同一状态的最大值):

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
#define INF 0x3f3f3f3f
struct MM{
	ll a[20];
	ll s;
}M1[maxn],M2[maxn];//两个结构体数组
int main(){
	ll T,n,m,k;
	scanf("%lld",&T);
	while(T--){
		  scanf("%lld %lld %lld",&n,&m,&k);
		  for(int i=0;i<n;i++){//初始化第一个 
		  	  scanf("%lld",&M1[i].s);//这里用结构体跟上
		  	  for(int j=0;j<k;j++){
		  	  	    scanf("%lld",&M1[i].a[j]);
				}
		  } 
		    for(int i=0;i<m;i++){//初始化第二个 
		  	  scanf("%lld",&M2[i].s);//同理结构体跟上
		  	  for(int j=0;j<k;j++){
		  	  	    scanf("%lld",&M2[i].a[j]);
				}
		  }
	  ll ans1=-INF,ans2=-INF;
	  ll ans=0;
		  for(int i=0;i<(1<<k);i++){//枚举每种对应的状态 比如 00   01  10  11这四个(把它想为二进制就好理解了)
		  	ans1=-INF,ans2=-INF;//这里注意每次都要设为-INF因为这样才能保证每次的枚举不会被上次的影响
		    for(int j=0;j<n;j++){//计算主武器,在同一状态下的最大值
		    	ll temp=0;
		  	    for(int p=0;p<k;p++){//这里就很巧妙了,利用p位移1并且能表示a[]对应的下标
		  	    	if(i&(1<<p)) temp+=M1[j].a[p];//判断是不是1;
		  	    	else temp-=M1[j].a[p];
		    		  }
				  ans1=max(ans1,temp+M1[j].s);
		    }
		    for(int j=0;j<m;j++){//计算副武器,在同一状态下的最大值
		    	  ll temp=0;
		    	  for(int p=0;p<k;p++){//这里也很巧妙
		    	  	if(i&(1<<p)) temp+=M2[j].a[p];//判断是不是1;
		    	  	else temp-=M2[j].a[p];
				  }
				  ans2=max(ans2,-temp+M2[j].s);//去最大值
			}
			ans=max(ans,ans1+ans2);
	    }
	    printf("%lld\n",ans);
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,但是根据提供的引用内容,我没有找到关于CSGO ntdll.dll修复的相关信息。如果您需要帮助,可以提供更多详细信息,我会尽力回答您的问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [CSGO 2018 cilent.dll](https://download.csdn.net/download/Sakura_Haruna/87264684)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [csgo参数.txt](https://download.csdn.net/download/qq_42950476/12505616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [market-csgo-api:与market.csgo.com API交互的模块(又名tm.csgo.com)](https://download.csdn.net/download/weixin_42137022/15716777)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值