题目链接:BZOJ 1076
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int K,N;
int a[50],v[50];
double dp[110][32800];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main(){
K=read(); N=read();
for(int i=1;i<=N;i++){
v[i]=read(); int x;
while(x=read()){
a[i]+=(1<<(x-1));//a[i]为第i件物品能够取的条件
}
}
for(int i=K;i>=1;i--){
for(int j=0;j<(1<<N);j++){
for(int p=1;p<=N;p++){
if((j&a[p])==a[p]){
dp[i][j]+=max(dp[i+1][j],dp[i+1][j|(1<<(p-1))]+(double)v[p]);
}
else dp[i][j]+=dp[i+1][j];
}
dp[i][j]/=(double)N;
}
}
printf("%.6lf",dp[1][0]);
return 0;
}
本文详细解析了BZOJ平台上的经典问题BZOJ1076的解决策略,通过动态规划与位运算的方法,有效地解决了物品选择与价值计算的问题。文章深入探讨了算法的实现细节,提供了清晰的代码示例,并解释了其背后的数学原理。
3987

被折叠的 条评论
为什么被折叠?



