1. 程式人生 > >洛谷P2473,[SCOI2008]獎勵關,概率期望

洛谷P2473,[SCOI2008]獎勵關,概率期望

正題

      題面輕戳

      這題考慮狀壓逆推。

      f[i][j]表示第1天到第i-1天取得寶物狀態為j,後面所拿到的最大價值。

      考慮轉移。

      f[i][j]=max(f[i+1][j],f[i+1][j|(1<<(i-1))]+d[i])

      不吃的話,那就直接繼承f[i+1][j],如果吃,那麼就可以看一下吃下這個寶物的價值 與 吃完這個寶物的“後繼效應”。

      不斷轉移。

      答案即為f[1][0]

不懂的看程式碼。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;

int K,n;
double f[110][1<<15];
int op[20];
int d[20];

int main(){
	scanf("%d %d",&K,&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&d[i]);
		int x;
		while(1){
			scanf("%d",&x);
			if(x==0) break;
			op[i]|=(1<<(x-1));//op[i]記錄的是吃i所需的前提條件。
		}
	}
	for(int i=K;i>=1;i--){
		for(int j=0;j<=(1<<n)-1;j++){
			for(int k=1;k<=n;k++)
				if((j&op[k])==op[k]) f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(k-1))]+d[k]);
				else f[i][j]+=f[i+1][j];//不滿足就直接繼承
			f[i][j]/=n;//平均情況,所以除以n
		}
	}
	printf("%.6lf",f[1][0]);
}