題解 USACO5 5 貳五語言Two Five

2022-04-29 22:03:14 字數 1975 閱讀 3408

一道記憶化搜尋題

題目定義一類行列均單調遞增的\(5\times5​\)矩陣,將其展開後所形成的字串按字典序編號.

題目要求實現編號與字串的相互轉換

​ 先不管字串與編號的相互轉換;

​ 給你一些限定條件(形如\((x,y)\)處只能填某字元),讓你求滿足條件的合法矩陣數

(1).暴搜

​ 有兩種思路,一種是按順序搜每乙個格仔放哪乙個字母,另一種是按順序搜每乙個字母放哪乙個格仔

​ 複雜度是\(o(25!)​\),過不了

​ 在這裡要特別注意第二種思路,記憶化也是在此基礎上進行

(2).記憶化

​ 在上面提到的第二種思路進行優化.

​ 既然是按照字母順序依次放到格仔裡,那麼會不會有一些美妙的性質呢?

​ 其實是有的,如下圖,可有以下性質:

a.已經填進去的數必在乙個聯通塊內.
​ 顯然應如此,否則中間的空肯定填不進更大的字母

b.聯通塊的輪廓線應是連續下降的折線
​ 如圖,藍塊是已經填好的塊

​ 假設綠塊是我現在要填字母的塊,如果填進去後,其上的黃塊必定將無字母可填(因為填字母是按順序填的!)

c.合法的聯通塊內具體的字母順序不影響剩下的字母填入
​ 因為以後將要填入的字母必定比現在所有已經填入的字母大,所以相互之間的"影響"是一致的

​ 綜上所述,我們可以使用記憶化搜尋(主要是由於性質c,性質a,b主要是方便設dp狀態)

​ 設記憶化陣列\(f[a][b][c][d][e]\) 表示第1,2,3,4,5行分別填了a,b,c,d,個數的情況下的可能合法矩陣數量,也就求出來求限制條件下的合法矩陣的數量.

​ (ps:可以借鑑一下排列的生成演算法,感覺本質上差不多qaq)

​ 即通過大家所說的逼近法來實現,

​ 現在有乙個合法矩陣對應的字串\(p=p_0p_1p_2...p_p_p_​\),那麼它的前面還有多少個滿足條件的字串呢?

​ 那麼,編號小於\(p\) 的合法矩陣的字串集合就很明確了,首先將字首為\(k_0(0的串加上,再加上\(k_0k_1(0,以此類推,加上\(k_0...k_i(0為字首的字串即可.

​ 再結合我們已經可以較快地求出一定限制條件下的合法矩陣的數量

​ 這題就到此終結了.

/*

此題要點:

1.要按字母的順序來搜

* 2.可以記憶化,用陣列f來實現 *

3.有值的f陣列的下標a,b,c,d,e應該遞減

4.最後用逼近法來完成任務

*/#include#define il inline

#define r register int

#define ll long long

#define gc getchar

using namespace std;

il int rd()

int s[26],ans;

inline bool check(int letter,int pos)

int f[6][6][6][6][6];

bool ok[30];

int dfs(int a,int b,int c,int d,int e,int letter)

if(b>s;

ans=0;

for(r i=0;i<25;i++) }

cout<>opt;

if(opt=='n')task1(rd());

else task2();

//dfs(0,0,0,0,0,1);

//cout<

return 0;

}

USACO5 5 矩形周長Picture

牆上貼著許多形狀相同的海報 它們的邊都是水平和垂直的。每個矩形可能部分或全部的覆蓋了其他。所有矩形合併後的邊長稱為周長。編寫乙個程式計算周長。如圖1所示7個矩形。如圖2所示,所有矩形的邊界。所有矩形頂點的座標都是整數。輸入輸出格式 輸入格式 輸入檔案的第一行是乙個整數 n 0 n 5000 表示有多...

USACO專題題解

思路 這道題的7種情況,我們可以把原圖存在s1,把目標存在s2裡面,然後各方法遍歷如下 1 先行從n到1變化,列從1到n變化 2 先列從n到1變化,行從n到1變化 3 先列從1到n變化,行從n到1變化 4 先列從n到1變化,行從1到n變化 5 先把每行進行逆序,然後執行1或2或3 6 把s1和s2比...

USACO郵票醜數題解

這兩道題可使用特殊的優化方法 醜數 include include include using namespace std int num 51 int f 5000001 int k,n,m,ans int tot 201 表示第j個數的值乘上第f tot j 大於當前尋找的醜數的前乙個醜數的最小...