傳送門
題意:有n種卡(n<=15),k輪遊戲,每輪遊戲可以抽一張卡(每一輪抽出每種卡的概率都是1/n),卡的價值為ai(ai可以為負數),並且某些卡需要另一些卡作為引導即只有在得到某些卡的時候才能獲得這些卡,每輪遊戲抽到的卡可以選擇獲得(前提是前驅卡已經獲得)或者不獲得,求選擇最優策略的情況下的總價值的期望。
題解:顯然可以使用比較容易理解的記憶化搜尋解決,定義dp[i][j]為第i輪狀態為j時,剩下操作能產生的最大價值,結果就是dp[1][0]
記憶化搜尋
#include
using
namespace std;
#define debug(x) cout<<#x<<" is "long
long ll;
const
int maxn=
1e3+5;
double dp[
105][(
1<<15)
];bool vis[
105][(
1<<15)
];ll a[21]
,w[21];
int n,k;
double
dfs(
int x,
int y)
else
}else
} vis[x]
[y]=1;
dp[x]
[y]/
=n;return dp[x]
[y];
}int
main()
}for
(int i=
0;iprintf
("%.6f\n"
,dfs(1
,0))
;return0;
}
也可以直接找出轉移方程直接dp(注意由於終點的狀態不唯一,而起點的狀態唯一,所以倒著進行dp就可以避免討論非法情況(可以這麼理解,由於終點狀態不確定,所以不管從**開始往起點轉移都是可以的,而正著轉移的狀態必須是以0為起點的,那麼就需要特別判斷用於轉移的狀態是否是從起點來的,這增加了不必要的麻煩(通常正著轉移的時候要使用乙個特殊值標記未被轉移的狀態避免用非法狀態轉移)))
#include
using
namespace std;
#define debug(x) cout<<#x<<" is "long
long ll;
const
int maxn=
1e3+5;
double dp[
105][(
1<<15)
];ll a[21]
,w[21];
int n,k;
intmain()
}for
(int i=k;i>=
1;i--
)else dp[i]
[j]+
=dp[i+1]
[j];
} dp[i]
[j]/
=n;}
}printf
("%.6f\n"
,dp[1]
[0])
;return0;
}
SCOI2008 獎勵關 題解(狀壓DP 期望)
題目鏈結 題目大意 給定 n 個寶物,每次隨機丟擲乙個寶物,獎勵分數為 p i 但如果選這個寶物必須選過它的前置寶物集合。共進行 k 輪問最優策略下的期望。n leq 15,10 6 leq p i leq 10 6 看到資料範圍,狀壓很容易想到。設 f i j 表示到了第 i 輪,寶物取捨狀態為 ...
BZOJ1076 獎勵關(狀壓期望dp)
好像noip一眼看去,全是dp。題面題意 有k個回合,n個物品,每回合隨機掉乙個物品i,有p i 的價值。可以選擇撿或不撿。對於每件物品,若想撿它,都要撿完它的先決物品,問最大期望價值。n 15,k 100。大概就是個狀壓dp,用f s i 表示i回合選了集合s的物品,所得到的最大期望。若每回合都必...
BZOJ 1076 獎勵關 狀壓期望DP
當前得分期望 上一輪得分期望 這一輪得分 m dp i,j 第i輪拿的物品方案為j的最優得分期望 如果我們正著去做,會出現從不合法狀態 比如前i個根本無法達到j這種方案 所以從後向前推 如果當前方案j裡具備了取k這個物品的條件 那麼dp i,j max 否則dp i,j dp i 1,j inclu...