Codeforces Round #676 (Div. 2) D. Hexagons (贪心&思维)

Codeforces Round #676 (Div. 2) D. Hexagons_其他

思路:对某一个范围的点的进行考虑,比如 C 1 , C 2 C_1,C_2 C1,C2 夹角区域的点,显然 C 4 , C 5 C_4,C_5 C4,C5两种操作不用考虑,然后因为 C 3 , C 6 C_3,C_6 C3,C6相互抵消,肯定至多考虑一种,所以六个操作变成了三个操作,然后又因为 C 2 C_2 C2操作等价于 C 1 + C 3 C_1+C_3 C1+C3,所
以只需比较两者花费,若 C 1 + C 3 C_1+C_3 C1+C3较小,则 C 2 C_2 C2不用考虑了,否则只需考虑 C 2 C_2 C2加上 C 1 C_1 C1,其他区域同理。

综上只需考虑两个操作就行了。

然后就是特判一下 x , y x,y x,y在那个象限然后进行相应最少步数的操作即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define lx x<<1
#define rx x<<1|1
#define reg register
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define il inline
ll c[7];
ll ans;
int main(){
	int t;scanf("%d",&t);
	while(t--){
		int x,y;
		scanf("%d%d",&x,&y);
		for(int i=1;i<=6;i++) scanf("%lld",&c[i]);
		c[1]=min(c[1],c[2]+c[6]); // 1 1
		c[2]=min(c[2],c[1]+c[3]); // 0 1
		c[3]=min(c[3],c[2]+c[4]); // -1 0
		c[4]=min(c[4],c[3]+c[5]); // -1 -1
		c[5]=min(c[5],c[4]+c[6]); // 0 -1
		c[6]=min(c[6],c[1]+c[5]); // 1 0
		if(x>=0&&y>=0){
			if(x>y) printf("%lld\n",y*c[1]+(x-y)*c[6]);
			else printf("%lld\n",x*c[1]+(y-x)*c[2]);
		}
		else if(x<=0&&y<=0){
			if(x>y) printf("%lld\n",(-x)*c[4]+(x-y)*c[5]);
			else printf("%lld\n",(-y)*c[4]+(y-x)*c[3]); 
		}
		else if(x>=0&&y<=0)
			printf("%lld\n",x*c[6]+(-y)*c[5]);
		else  printf("%lld\n",(-x)*c[3]+y*c[2]);
	}
	return 0;
}

总结:对于多操作的贪心问题,常常考虑等效操作,取最优的进行贪心选择。