bzoj 3041: 水叮噹的舞步
這是道ida*,迭代加深+估價剪枝;
首先考慮估價函式,一般情況下我們把易於計算的操作次數的下限作為a*的估價函式,易知這道題裡每次有效操作只會向外拓寬乙個顏色層,那麼估價函式就可以確定為剩下未被拓展的顏色層數。這個層數就是答案,這個數的下限就是剩餘未探索的顏色數,道理顯然。我們把乙個難以確定的準確函式用乙個相對嚴格但便於計算的估價函式替代去進行搜尋,這就是a*演算法的精要。一般情況下,這個函式可以設為錯位個體的個數,但要相對嚴格以保證正確性。
其次,這道題卡常;裸的ida*剪枝在這道題codevs資料上只能跑到60%,所以要考慮優化演算法過程。這種題一般最先想到的都是flood fill演算法,每一次更新狀態都要o(
n2) o(n
2)
的時間複雜度確定邊界情況,去更新到下乙個狀態。但由於更新使顏色發生變化的點數量實在有限,所以我們考慮在更新的時候直接使用父親狀態的flood fill值,這樣可以在狀態更新時優化到大概o(
n)o (n
)的極優複雜度。
事實上,單純地關注**,我們會發現這個過程也需要遍歷整個地圖,但是它和flood fill的最大差別,在於它的更新操作太少,在實際執行上優勢巨大。我們也可以用鍊錶把這個過程優化到嚴格o(n)o最後,在回溯操作的時候,直接暴力將父親狀態的flood fill值回滾就可以了。至於**為什麼要有結構體寫,我也不知道qwq(n
),但限於碼力有限,這個想法我沒有實現,寫在這裡共大家交流。
當然,這裡複雜度的分析大多是我的主觀臆斷,若有紕漏希望指出。
ac**:
#include
#define inf 1000000000
#define fair(x) (x>=1&&x<=n)
using
namespace
std;
int n,maxstep=0,ans=inf;
struct type
};struct node
}a,b,zero;
int xt[4]=;
int yt[4]=;
inline
int judge()
void explore(int x,int y,int col)
}}int fill(int col)
return cnt;
}void dfs(int step)
if(step+now>maxstep)return;
node t=b;
for(register
int i=0;i<=5;i++)
dfs(step+1);
b=t;
}}int main()
printf("%d\n",ans);
}}
水叮噹的舞步 深搜
背景background 水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 描述description 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選...
JZOJ 3422 水叮噹的舞步
水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選擇乙個0 5之間的顏色,然後輕輕地跳動一步,地毯左上角...
水叮噹的舞步(迭代搜尋 A 搜尋)
題目描述 水叮噹得到了一塊五顏六色的格仔形地毯作為生日禮物,更加特別的是,地毯上格仔的顏色還能隨著踩踏而改變。為了討好她的偶像虹貓,水叮噹決定在地毯上跳一支輕盈的舞來賣萌 地毯上的格仔有n行n列,每個格仔用乙個0 5之間的數字代表它的顏色。水叮噹可以隨意選擇乙個0 5之間的顏色,然後輕輕地跳動一步,...