样例不过悬关求调状压dp
查看原帖
样例不过悬关求调状压dp
1023793
yaodiguoan楼主2024/11/27 13:59
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
//#pragma GCC optimize(3, "Ofast", "inline")
#define hh putchar('\n')
#define kg putchar(' ')
//#define debug puts("debug")
//#define int long long
//#define int __int128
namespace quickread{
	template<typename T> void read(T &x){
		x=0;char c=getchar();T neg=0;
		while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
		while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
		if(neg) x=(~x)+1;
	}
	template<typename T> void write(T x){
		if(x<0) putchar('-'),x=~x+1;
		if(x>9) write(x/10);
		putchar(x%10^48);
	}
	inline string readstr(){
    	char ch=getchar();string str="";
		while(!isalnum(ch)) ch=getchar();
		while(isalnum(ch)){str+=ch;ch=getchar();}
		return str;
	}
	inline char readchar(){
		char ch=getchar();
		while(!isalnum(ch)) ch=getchar();
		return ch;
	}
	inline void putstr(string s){
		int len=s.length();
		for(int i=0;i<len;++i) putchar(s[i]);
	}
}
using namespace quickread;
int n,m,tot,dp[1<<20][20],id[110][110],ans=2147483647;
struct node{int sx,sy,ex,ey,col;}; 
node a[30];
vector<int> pre[30];
void update(int x){for(int i=a[x].sx;i<=a[x].ex;++i) for(int j=a[x].sy;j<=a[x].ey;++j) id[i][j]=x;}
bool check(int x,int tim){
	bool tag=1;
	for(int y:pre[x]) tag&=(tim&(1<<y));
	return tag;
}
bool check_col(int tim,int x,int col){
	if(!pre[x].size()) return true;
	for(int i=0;i<n;++i) if(i^x&&tim&(1<<i)&&!(col^a[i].col)) return 1;
	return 0;
}
signed main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0);cout.tie(0);
	read(n);tot=1<<n;
	for(int i=0;i<n;++i) read(a[i].sx),read(a[i].sy),read(a[i].ex),read(a[i].ey),read(a[i].col),update(i),m=max(m,a[i].col);
//	for(int i=1;i<100;++i) for(int j=1;j<100;++j) write(id[i][j]),(j==99?hh:kg);
	for(int i=0,x;i<n;++i){
		x=a[i].sx;if(!x) continue;
		if(i^id[x-1][a[i].sy]) pre[i].push_back(id[x-1][a[i].sy]);
		for(int j=a[i].sy+1;j<=a[i].ey;++j) if(i^id[x-1][j]&&id[x-1][j-1]^id[x-1][j]) pre[i].push_back(id[x-1][j]);	
	} 
	memset(dp,0x3f,sizeof(dp));
	for(int i=1;i<=m;++i) dp[0][i]=1;
	for(int i=1;i<tot;++i)
		for(int j=0;j<n;++j)
			if((i>>j)&1 && check(j,i)) for(int k=1;k<=m;++k)
				if(check_col(i,j,k)) dp[i][a[j].col]=min(dp[i][a[j].col],dp[i^(1<<j)][k]+(bool)a[j].col^k);
	for(int i=1;i<tot;++i)
//		for(int j=0;j<n;++j) write(i),putchar(','),write(j),kg,write(dp[i][j]),hh; 
	for(int i=1;i<=m;++i) ans=min(ans,dp[tot-1][i]);
	write(ans);
	return 0;
}


这篇题解的思路

2024/11/27 13:59
加载中...