状压概率DP 70pts求助
查看原帖
状压概率DP 70pts求助
227728
冰糖鸽子TJ鸽子协会楼主2021/5/30 18:14

RT,错了357,都是在第一位就小了


// Problem: P2473 [SCOI2008] 奖励关
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P2473
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
#define M 20
#define int long long
int n,m,fff,a[M],Xn,nd[M],bit[M+5];
long double f[M][700000];
long double max(long double x,long double y)
{
	return (x<y?y:x);
}
signed main()
{
	cin>>m>>n;bit[1]=1;Xn=pow(2,n-1);
	for(int i=2;i<=M;i++) bit[i]=bit[i-1]*2;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i]>>fff;
		while(fff)
		{
			nd[i]+=bit[fff];
			cin>>fff;
		}
	}
	// for(int i=1;i<=n;i++) cout<<nd[i]<<' ';
	for(int i=m;i>0;i--)
	{
		for(int j=0;j<Xn;j++)//0 1
		{
			for(int k=1;k<=n;k++)//1 2
			{
				if((j&nd[k])==nd[k])
				{
					//可选拿不拿
					f[i][j]+=max(f[i+1][(j|bit[k])]+a[k],f[i+1][j]);//前拿后不拿
				}
				else
				{
					f[i][j]+=f[i+1][j];
				}
				// cout<<f[i][j]<<endl;
			}
			f[i][j]/=1.0*n;
		}
	}
	printf("%.6Lf",f[1][0]);
	return 0;
}
2021/5/30 18:14
加载中...