1. 程式人生 > >POJ1691平板塗色

POJ1691平板塗色

iostream 混合 href 部分 次數 sdi 我只 amp 方案

題目描述

原題來自:POJ 1691

CE 數碼公司開發了一種名為自動塗色機(APM)的產品。它能用預定的顏色給一塊由不同尺寸且互不覆蓋的矩形構成的平板塗色。

技術分享圖片

為了塗色,APM 需要使用一組刷子。每個刷子蘸了顏色 C 。APM 拿起一把蘸有顏色 C 的刷子,並給所有顏色為 C 的矩形塗色。請註意,塗色有順序要求:為了避免顏料滲漏使顏色混合,一個矩形只能在所有緊靠它上方的矩形塗色後,才能塗色。例如圖中矩形 F 必須在 C 和 DDD 塗色後才能塗色。註意,每一個矩形必須立刻塗滿,不能只塗一部分。

寫一個程序求一個使 APM 拿起刷子次數最少的塗色方案。註意,如果一把刷子被拿起超過一次,則每一次都必須記入總數中。

輸入格式

第一行為矩形的個數 N 。
下面有 N 行描述了 N 個矩形。每個矩形有 555 個整數描述,左上角的 y 坐標和 x 坐標,右下角的 y 坐標和 x 坐標,以及預定顏色。

輸出格式

一行一個整數,表示拿起刷子的最少次數。

樣例

樣例輸入

7
0 0 2 2 1
0 2 1 6 2
2 0 4 2 1
1 2 4 4 2
1 4 3 6 1
4 0 6 4 1
3 4 6 6 2

樣例輸出

3

數據範圍與提示

對於全部數據,1N14,顏色號為 1 到 20 的整數。保證平板的左上角坐標總是 (0,0),坐標的範圍是 09 。


我只想吐槽CE公司這個名字不太吉利

這道題比較水,一個簡單的DFS就能過,只不過加一點貪心的思想 為了盡量少的拿起刷子,我們在一種顏色可以塗的情況下,一定要盡量多的塗 下面給出代碼:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include
<cstring> #include<string> #include<algorithm> using namespace std; inline int rd(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c==-) f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-0; return x*f; } inline void write(int x){ if(x<0) putchar(-),x=-x; if(x>9) write(x/10); putchar(x%10+0); } struct node{int sx,sy,ex,ey,co;}s[100000]; bool cmp(const node &x,const node &y){ if(x.sx!=y.sx) return x.sx<y.sx; return x.sy<y.sy; } int n,m; int color[1000],book[1000][1000],used[1000]; int ans=99999; bool check(int x){//對於一塊區域,是否能塗 for(int i=1;i<=n;i++) if(book[x][i]&&!used[i]) return 0; return 1; } void dfs(int step,int sum,int la){//分別是用了幾次,塗了幾塊,和上一個塗的 if(step>=ans) return ; if(sum==n){ ans=min(ans,step); return ; } for(int i=1;i<=m;i++){//盡量用同種顏色 int cnt=0; if(i!=la&&color[i]!=0){ for(int j=1;j<=n;j++){ if(used[j]==0&&s[j].co==i&&check(j)==1){//能塗就塗 used[j]=1; cnt++; } else if(used[j]!=0&&s[j].co==i) used[j]++; } if(cnt>0) dfs(step+1,sum+cnt,i);//如果有可以塗色的,就繼續搜索 for(int j=n;j>=1;j--){ if(used[j]==1&&s[j].co==i&&check(j)==1){//賦原來的值 used[j]=0; cnt--; } else if(used[j]>1&&s[j].co==i) used[j]--; } } } return ; } int main(){ n=rd(); int i,j,k; for(i=1;i<=n;i++){ s[i].sx=rd(),s[i].sy=rd(),s[i].ex=rd(),s[i].ey=rd(),s[i].co=rd(); s[i].sx++; s[i].sy++; color[s[i].co]++; } for(i=1;i<=20;i++) if(color[i]) m=i; sort(s+1,s+n+1,cmp);//按照需要塗色順序排列 for(i=2;i<=n;i++) for(j=i-1;j>=1;j--) if(s[i].sx==s[j].ex+1&&((s[i].sy>=s[j].sy&&s[i].sy<=s[j].ey)||(s[i].ey>=s[j].sy&&s[i].ey<=s[j].ey)))//記錄對於排序後的第i個塗色區域有那幾個先行條件 book[i][j]=1; dfs(0,0,0); write(ans); return 0; }

POJ1691平板塗色