由於遞推的時候依賴於三個連續層的關係.一開始想著直接三重for迴圈,但是這裡有個問題就是上一層的0位置上包括著上上層是0和1兩種可能,而後者又對當前行有約束,因此該方法不行.當然有乙個辦法就是增加狀態數,讓狀態能夠表示是從1還是從0轉移過來的.(這題有個解法是採用多進製的狀態壓縮). 網上瞄了別人的一眼解題報告. 瞬間頓悟,竟然三層之間發生關係,那麼就直接把連續的兩層記錄起來,雖然說空間上不及多進製優美. 但是卻能夠去描述這些個問題.
**如下:
#include #include#include
#include
using
namespace
std;
/*題意:給定乙個矩陣,有點點能夠放置部隊,有的不行,部隊能夠進攻上下左右各2個格仔,現在
問要求所有部隊火力不能夠覆蓋友方部隊,問最多能夠擺放多少部隊.
解法:其實這題單單就一行的狀態來說,狀態的約束條件更強,可以預見其合法狀態也很少,何
況給定列本身就不超過10, 因此一行中的合法狀態一定很少. 該題難點在於如何將上下
火力不覆蓋友方部隊很好的表示出來.乙個可行的做法是對設定狀態是dp[k][i][j]表示
第k層的狀態為i,第i-1層狀態為j時最多放置多少部隊. 所以又動態方程:
dp[k][i][j] = sum(dp[k-1][j][k]) 其中k滿足不和i發生衝突
*/int n, m, sta[65], idx; //
當m=10的時候,合法的狀態不超過65個
int g[105], dp[105][65][65]; //
該dp的第一維真正意義上表示乙個狀態,而不是狀態的下表
void display(int
x)
else printf("0 "
); }
puts(
"");
getchar();
}void dfs(int pos, int statu, int
dist)
dfs(pos+1, statu<<1, dist+1
);
if (dist >= 2) }
bool legal(int x, int
y) bool judge(int x, int
y) int
get(int
x) }
return
ret;
}int
dp()
}
return
ret;
}//初始化第一,二層的狀態
for (int i = 1; i <= idx; ++i) }}
for (int k = 3; k <= n; ++k)
for (int m = 1; m <= idx; ++m)
}dp[k][i][j] += get
(sta[i]);}}
}for (int i = 1; i <= idx; ++i)
}return
ret;
}int
main()
}printf(
"%d\n
", dp());
}return
0;
}
POJ 1185 炮兵陣地(動態規劃 狀態壓縮)
炮兵陣地 description 司令部的將軍們打算在n m的網格地圖上部署他們的炮兵部隊。乙個n m的地圖由n行m列組成,地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如...
poj 1185 炮兵陣地
題目鏈結 題意 在n m的網格地圖上部署炮兵部隊。地圖的每一格可能是山地 用 h 表示 也可能是平原 用 p 表示 如下圖。在每一格平原地形上最多可以布置一支炮兵部隊 山地上不能夠部署炮兵部隊 一支炮兵部隊在地圖上的攻擊範圍如圖中黑色區域所示 如果在地圖中的灰色所標識的平原上部署一支炮兵部隊,則圖中...
POJ 1185 炮兵陣地
include include include include include include include include include include include include include include define sz v int v size define rep i,n ...