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;
}
总结:对于多操作的贪心问题,常常考虑等效操作,取最优的进行贪心选择。