枚举子集还有优化的空间吗?
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define F(i,k,n) for (int i=k;i<=n;i++)
typedef long long ll;
const int N=24;
int n,m,k;
int x[N],y[N],a[N];
int pre[]={1,4,16,64,256,1024,4096,16384,65536
,262144,1048576,4194304,16777216};
int dp[1<<N];
int to[N];
int dx[]={0,0,0,1,-1};
int dy[]={0,1,-1,0,0};
int get_1(int a){
int sum=0;
for (int i=a;i;i=i&(i-1)) sum++;
return sum;
}
bool pan(int a){
int tot=0;
F(i,0,k-1){
if ((a>>i)&1){
tot++;
to[tot]=i;
}
}
if (tot==1) return 1;
F(i,1,tot){
F(j,0,4){
int l=x[i]+dx[j],r=y[i]+dy[j];
bool flag=1;
F(p,1,tot){
if (abs(x[to[p]]-l)+abs(y[to[p]]-r)>1) flag=0;
}
if (flag) return 1;
}
}
return 0;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>m>>k;
F(i,0,k-1) cin>>x[i]>>y[i]>>a[i];
int op=0;
F(i,0,k-1) op+=pre[i]*a[i];
memset(dp,0x3f,sizeof dp);
dp[0]=0;
F(s,1,op){
int q=s,flag=0;
for (int i=k-1;i>=0;i--){
if (q/pre[i]>a[i]) flag=1;
q%=pre[i];
}
if (flag) continue;
int change=0,d=s;
for (int i=k-1;i>=0;i--){
if (d>=pre[i]) change+=(1<<i);
while (d>=pre[i]) d-=pre[i];
}
for (int j=change;j>=0;j=(j-1)&change){
if (pan(j)){
int l=0;
F(i,0,k-1) if ((j>>i)&1) l+=pre[i];
dp[s]=min(dp[s],dp[s-l]+1);
}
if (!j) break;
}
}
cout<<dp[op];
return 0;
}