37分求调
  • 板块P1283 平板涂色
  • 楼主Druid
  • 当前回复2
  • 已保存回复2
  • 发布时间2024/10/12 19:30
  • 上次更新2024/10/12 21:22:12
查看原帖
37分求调
431095
Druid楼主2024/10/12 19:30
#include <bits/stdc++.h>
using namespace std;
struct node {
	int px1;
	int px2;
	int py1;
	int py2;
	int clr;//颜色
} tgs[21];//长方形的英文,代表长方形块

bool cmp(node a, node b)//排序函数
{
	return a.py1 < b.py1;
}

int lbit(int x)//lowbit函数
{
	return x & -x;
}

int t;//log2的临时变量
int log2(int x)//log2函数
{
	t = 0;
	while (x > 0) {
		x = x >> 1;
		t++;
	}
	return t-1;
}

int n, dp[191981][21], k, dg, vis[114], cl, sz;
//dp第一项表示状态,第二项表示颜色,k是临时变量,dg表示位数的临时变量
//visit用来打表,cl是存颜色的临时变量,sz是记录入度个数的临时变量

bool flag;
vector<int> fa[21];
int main()
{
	//freopen("1.txt","w",stdout);
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> tgs[i].px1 >> tgs[i].py1 >> tgs[i].px2 >> tgs[i].py2 >> tgs[i].clr;//输入
		
	sort(tgs, tgs + n, cmp);//排序
	for(int i=0;i<n;i++)
	{
		//cout<<"\n"<<i<<"  ";
		if(tgs[i].py1==0)//如果y1在最上面就在vis上打表
		{
			for(int j=tgs[i].px1;j<tgs[i].px2;j++)//左闭右开
				vis[j]=i;
			continue;
		}
		
		k=vis[tgs[i].px1];//统计位于上面的正方体
		fa[i].push_back(k);
		//cout<<" "<<k;
		for(int j=tgs[i].px1;j<tgs[i].px2;j++)
		{
			if(k!=vis[j])
			{
				k=vis[j];
				fa[i].push_back(k);
				//cout<<" "<<k;
			}
			vis[j]=i;//边统计边覆盖
		}
	}//在排序后的基础上算入度
	
	for (int i = 0; i <= 20;i++)//初始化dp
		dp[0][i] = 1;
		
	for (int i = 1; i < (1<<n); i++) {
		k = i;
		//cout<<"\n"<<i<<"  ";
		for(int j=1;j<=20;j++)//初始化
			dp[i][j] = 11451419;
		while (k > 0) //k枚举从哪个状态得来
		{
			dg = log2(lbit(k));
			cl = tgs[dg].clr;
			//cout<<"k:"<<k<<" clr:"<<cl<<"\n";
			flag=1;
			//cout<<" "<<k;
			sz=fa[dg].size();
			//cout<<sz<<" ";
			//cout<<fa[dg][0];
			for(int j=0;j<sz;j++)
			{
				flag=(i>>fa[dg][j])%2;//入度检测
				if (flag)
					break;
			}
			if(!flag)
			{
				k-=lbit(k);//减去lowbit
				continue;
			}
			
			for (int j = 1; j <= 20; j++)//dp传递
				if (cl == j)
					dp[i][cl] = min(dp[i][cl], dp[i - lbit(k)][cl]);
				else
					dp[i][cl] = min(dp[i][cl], dp[i - lbit(k)][j] + 1);
				//cout<<j<<" "<<(cl==j)<<" "<<dp[i][cl]<<"\n";
			k-=lbit(k);//减去lowbit
		}
		/*mn = 11451418;
		for (int j = 1; j <= 20; j++)
		{
			mn = min(dp[i][j], mn);
		}
		//cout<<mn<<"\n";*/
	}
	int ans = 11451419;
	for (int i = 1; i <= 20; i++)//求各种颜色中的最小值
		ans = min(ans, dp[(1<<n) - 1][i]);
	cout << ans;
	return 0;
}

2024/10/12 19:30
加载中...