那天學習的是狀態壓縮。
普通的dp遇到狀態比較多的時候就變得要開n維的陣列,當然不可能開這麼大的陣列,這是不科學的。
那麼就一定有乙個救世主一樣的方法存在,可以把這個問題解決。這個救世主就是——狀態壓縮。
狀態壓縮,顧名思意,就是把很多的狀態壓縮起來,壓成乙個狀態。這就比較容易操作,進行dp了。而比較常見的壓縮方法就是把狀態化為二進位制。然後用位操作的方法去完成其中的一些操作。這就會是時間複雜度減少許多。
空講並沒有什麼卵用。所以還是上一道例題來用實力說話。
題目大意:題解:在乙個n*m(1<=n,m<=12)的田地中種玉公尺,有些格仔不能放,要求不能有任何兩個玉公尺相鄰,問有多少種方法(方法數mod 100000000)。
sample input
2 3
1 1 1
0 1 0
sample output
9
#include
#include
#include
using
namespace
std ;
const
int mod=100000000;
long
long f[15][2
<<12];
long
long corn[15],data[2
<<12];
intmap[15][15];
int n,m;
int main()
}int c=0;
for (int i=0;i<=(1
<1;i++)
if (!(i&(i<<1)))
data[++c]=i;
for (int i=1;i<=c;i++)
if (!(corn[1]&data[i]))
f[1][i]=1;
for (int i=2;i<=n;i++)
for (int j=1;j<=c;j++)
if (!(data[j]&corn[i]))
for (int k=1;k<=c;k++)
long
long ans=0;
for (int i=1;i<=c;i++)
ans=(ans+f[n][i])%mod;
printf("%d\n",ans);
return
0;}
程式翻譯【即大概流程
1.讀入
2.土地用二進位制存起來(0 表示可以種,1 則表示不行
3.在不計算土地限制的情況下所有玉公尺種植的可行方案用二進位制記錄起來。
4. 先把第一行做出來,以此作為基礎來進行dp,擴充套件出下面的所有方案。
5. 迴圈所有玉公尺種植方案。在合法的情況下,累加所有的可能方案。
6. 累加所有可行方案
7. 輸出
時間複雜度大概是o(
2m)2
×n而且這只是最壞情況,實際上根本不可能會是這種情況,因為有剪枝。
其實狀壓的精華就在於把有沒有種植玉公尺的狀態變成二進位制的「0」和「1」。
接下來就是幾道當天做的題目:
司令部的將軍們打算在n*m的網格地圖上部署他們的炮兵部隊。乙個n*m的地圖由n行m列組成,地圖的每一格可能是山地(用」h」 表示),也可能是平原(用」p」表示),如下圖。在每一格平原地形上最多可以布置一支炮兵部隊(山地上不能夠部署炮兵部隊);一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示:題解:如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中的黑色的網格表示它能夠攻擊到的區域:沿橫向左右各兩格,沿縱向上下各兩格。圖上其它白色網格均攻擊不到。從圖上可見炮兵的攻擊範圍不受地形的影響。 現在,將軍們規劃如何部署炮兵部隊,在防止誤傷的前提下(保證任何兩支炮兵部隊之間不能互相攻擊,即任何一支炮兵部隊都不在其他支炮兵部隊的攻擊範圍內),在整個地圖區域內最多能夠擺放多少我軍的炮兵部隊。
input
第一行包含兩個由空格分割開的正整數,分別表示n和m; 接下來的n行,每一行含有連續的m個字元(『p』或者』h』),中間沒有空格。按順序表示地圖中每一行的資料。n <= 100;m <= 10。
output
僅一行,包含乙個整數k,表示最多能擺放的炮兵部隊的數量。
sample input
5 4
phpp
pphh
pppp
phpp
phhp
sample output
6
#include
#include
#include
using namespace std ;
intmap[105];
int num[105],sum[105];
int f[105][100][100];
int get(int
x) return c;
}int main()
}int c=0;
for (int i=0;i<1
if (n==1)
for (int i=1;i<=c;i++)
for (int j=1;j<=c;j++)
if ((!(num[i]&map[1]))&&(!(num[j]&map[2]))&&(!(num[i]&num[j])))
f[2][i][j]=sum[i]+sum[j];
for (int i=3;i<=n;i++)
for (int i=1;i<=c;i++)
for (int j=1;j<=c;j++)
if ((!(num[i]&map[n-1]))&&(!(num[j]&map[n]))&&(!(num[i]&num[j])))
ans=max(ans,f[n][i][j]);
printf("%lld\n",ans);
return
0;}
題目:
給出乙個w行h列的廣場題解:用1*2小磚鋪蓋,小磚之間互相不能重疊
問有多少種不同的鋪法?
1<=w,h<=11
#include
#include
#include
#include
using
namespace
std ;
int n,m;
long
long f[15][1
<<15];
void dfs(int i,int j,int k1,int k2)
if (k1&now)
dfs(i,j+1,k1,k2);
}else
}int main()
dfs(1,1,(1
<1,0);
for (int i=2;i<=n;i++)
for (int j=0;j<=1
dfs(i,1,j,0);
}printf("%lld\n",f[n][(1
<1]);
}return
0;}
end 2016 8 5 Unity學習筆記三(常用方法)
1.destory內容destory方法可刪除所有繼承自 object 類的元件 使用方法 destory gameobject destory gameobject,time time s 之後進行刪除 另外說一點 gameobject 在指令碼中的意思以為著當前繫結的gameobject。gam...
學習後總結,總結後再學習
學習後總結,總結後再學習 2010年畢業以來,讀了幾百本書籍,包括it技術 管理 歷史 營銷 金融 心理等等,在讀某商學院mba一年後感覺有些東西還是要寫寫,除了能增加自己對某些知識和理論的理解外,也許其他人也碰巧想關注一下,了解這方面的東西。我所寫的都是一些簡單的概念層面的解釋,不會做太深入的闡述...
學習總結 近期acm學習的總結
開學已經乙個月了,對acm的學習也乙個月了,做了一下總結 對自己不好的地方的反省 1.開學一開始學的是stl,不得不說stl是乙個很好的東西,熟練的運用stl大大的減少了 量,也使演算法容易實現。但是我在用stl後使自己產生了一種惰性思維。在兩個星期的stl練習後,我發現自己變得越來越懶,不願意自己...