N 人 (≤10) 參賽 M 題 (≤1000),每人每題有解對概率。每題派一人,任意時刻任意兩人解題數差 ≤ 1。求最大期望解對題數。
dp[i][mask]:前 i 題,mask (N 位) 表示哪些人已在當前輪次解過題 (1=已解,0=未解)。dp[0][0]=0,其餘 -inf。nmask = mask | (1<。若 nmask == (1< (所有人都解過一輪),則重置 nmask=0 (進入下一輪)。 dp[i][nmask] = max(dp[i][nmask], dp[i-1][mask] + p[k][i])。max(dp[M][*])。狀態數 M × 2^N ≤ 1000 × 1024 = 1e6,轉移 O(N),總操作 ~1e7,C++ 0.1s 內完成。
#include
using namespace std;
const int MAXM = 2005, MAXS = 1024;
double p[11][MAXM], dp[MAXM][MAXS];
int main() {
int T, cas=1; scanf("%d", &T);
while(T--) {
int N, M; scanf("%d%d", &N, &M);
for(int i=0;i -1e50) {
for(int k=0;k
將每輪 N 題建為二分圖 (人 → 題),邊權為概率,跑 N 次最大費用最大流 (每輪流量 N),總複雜度較高但思路清晰。DP 更優。