题目:https://www.luogu.org/problemnew/show/P2473
还是对DP套路不熟悉...
像这种前面影响后面,而后面不影响前面的问题就应该考虑倒序递推;
看n只有15那么考虑状压,期望什么的就是除一下n就行了。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,k,p[20],cnt[20],s[20]; double f[105][1<<15]; int main() { scanf("%d%d",&k,&n); for(int i=1,x;i<=n;i++) { scanf("%d",&p[i]); while(scanf("%d",&x)==1) { if(!x)break; s[i]|=(1<<(x-1)); } } for(int i=k;i;i--) { for(int j=0;j<(1<<n);j++) { for(int l=1;l<=n;l++) { if((s[l]|j)==j) f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(l-1))]+p[l]); else f[i][j]+=f[i+1][j]; } f[i][j]/=n; } } printf("%.6lf",f[1][0]); return 0; }