E. Light Up the Grid 题解
[ E. Light Up the Grid ] ( Problem - E - Codeforces )
题解待补……
总之是把2*2网格看成二进制码,每种操作相当于异或操作,预处理16个操作的代价,把每种状态连边,然后跑反向边最短路。
剩下的之后再补~(想不起来就不补了 😛
代码
#include <bits/stdc++.h>
using namespace std;
//-------------------------------------------------------------------------------------------
#define int long long
#define lost_R ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define P pair<int,int>
#define lowbit(x) (x&(-x))
#define dbg1(x) cout<<"# "<<x<<endl
#define dbg2(x,y) cout<<"# "<<x<<" "<<y<<endl
#define endl '\n'
const int mod=998244353;
const int N=1<<16;
const int INF=0x3f3f3f3f3f3f3f3f;
const int inf=0x3f3f3f3f;
using ar3=array<int,3>;
using ar2=array<int,2>;
//--------------------------------------------------------------------------------------
int a0,a1,a2,a3;
int m;
vector<P> g[N];
int op[16];
struct info{
int dis,id;
bool operator < (const info &t) const {
return t.dis<dis;
}
};
priority_queue<info> q;
int dist[N],vis[N];
void dij(int s){
fill(dist,dist+N,inf);
dist[s]=0;
q.push({0,s});
while(!q.empty()){
auto [d,x]=q.top();
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(auto [y,dis]:g[x]){
if(dist[y]>dist[x]+dis){
dist[y]=dist[x]+dis;
q.push({dist[y],y});
}
}
}
}
void init(){
op[0]=min({8*a0,4*a1,4*a2,2*a3});
op[1]=op[2]=op[4]=op[8]=a0;
op[3]=op[12]=min(2*a0,a1);
op[5]=op[10]=min(2*a0,a2);
op[6]=op[9]=min(2*a0,a1+a2);
op[7]=op[11]=op[13]=op[14]=min({3*a0,a0+a3,a0+a1+a2});
op[15]=min({4*a0,a3,2*a1,2*a2});
for(int mask=0;mask<(1<<16);mask++){
for(int oper=0;oper<16;oper++){
int next_mask=0,cost=op[oper];
for(int bit=0;bit<16;bit++){
if(mask&(1<<bit)){
int next_bit=bit^oper;
if(next_bit!=15) next_mask|=(1<<next_bit);
}
}
g[next_mask].push_back({mask,cost});
}
}
dij(0);
}
void solve(){
cin>>m;
int mask=0;
for(int i=1;i<=m;i++){
int x=0;
string t;
cin>>t;
x+=(t[0]-'0')<<3;
x+=(t[1]-'0')<<2;
cin>>t;
x+=(t[0]-'0')<<1;
x+=(t[1]-'0')<<0;
mask|=(1<<x);
}
cout<<dist[mask]<<endl;
}
signed main(){
lost_R;
// freopen("jia.in","r",stdin);
// freopen("jia.out","w",stdout);
int T=1;
cin>>T>>a0>>a1>>a2>>a3;
init();
for(int i=1;i<=T;i++){
solve();
}
return 0;
}

浙公网安备 33010602011771号