題意:我方有n個士兵,敵方有m個,每方士兵都有乙個血量,現在有k輪無差別炮火打擊,每次都會從存活的士兵中隨機選一人,這名士兵的hp就-1,問對方被團滅的概率有多大?
思路:因為n和m的範圍很小,我們可以考慮暴力搜尋,中間使用記憶化。這裡狀態壓縮有乙個小技巧,我們的正常想法是:因為士兵總數最多只有10個,我們可以用乙個十位數來表示狀態,每一位數代表這個士兵的現在的hp。但是我這樣設計狀態超時了。。。網上的狀態設定的比較巧妙,網上用了12位數來表示狀態,每一位代表敵方或者我方的hp為某個值的士兵還剩多少個。這樣設計狀態的好處在於如果有多個士兵的hp相同,那麼只需向下搜尋乙個就行了,大大減少了搜尋的分支。
**:
#include #define ll long long#define db double
using namespace std;
mapdp;
int now_state[2][7];
int n, m;
ll limit;
ll get_state(void)
db dfs(ll state, int deep)
dp[state] = ans;
return ans;
} int main()
for (int i = 1; i <= m; i++)
printf("%.7lf\n", dfs(get_state(), k));
}
GYM 101933E(記憶化搜尋)
用每個人的血量作為狀態去搜尋t飛,考慮題解中更好的搜尋方式 每種血量有多少個人作為狀態。這樣會減去很多重複的狀態,因為只要乘一下就得到了所有相同情況的和。雖然我不會算,但是直觀感受起來複雜度比較優秀。include include using namespace std typedef double...
Gym 101889E 記憶化搜尋
思維還是太將江華,開始一直想dp,就是這一位餘數固定時取最小的乙個字串,但是字串太大,賦值的時候超時,其實根本沒必要存字串,只要記憶化搜尋,看看 pos res 這個狀態是否能構成就行,這樣的話1000 1000個狀態,穩穩的,然後貪心從小列舉,第乙個可行的一定是最優解。includeusing n...
交換遊戲 狀態壓縮 記憶化搜尋
題目描述 一列上有12個孔,這12個孔中有些孔被遮擋住了。假定我們用 來表示沒被遮擋住的孔,用 o 來表示被遮擋住的孔。如果相鄰的三個孔有兩個孔被遮擋,並且被遮擋的兩個孔相鄰,就是 oo 和 oo 對於這樣的三個孔,我們可以將中間的孔的遮擋物移開,代價是將一端的遮擋物移到另一端沒有被遮擋的孔上面。對...