BZOJ1076 [SCOI2008] 奖励关
题目大意:从后往前推,每次操作要枚举每种宝物,分取和不取2种情况,状态要用二进制存。正推不太好判断...于是倒推,意义就变成了:要想取得某个物品,先需要支付当前物品的代价,这样DP就没问题了。
附代码:
View Code
/************************************************************** Problem: 1076 User: 1012haoyifan Language: C++ Result: Accepted Time:1156 ms Memory:53496 kb ****************************************************************/ #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define P(i) (1<<(i-1)) using namespace std; double f[102][65536]; int N,K,t; int v[20]; int d[20]; int main() { //freopen("in","r",stdin); scanf("%d%d",&N,&K); for (int i=1;i<=K;i++) { scanf("%d",&v[i]); scanf("%d",&t); while (t) { d[i]+=P(t); scanf("%d",&t); } } for (int i=N;i;i--) for (int j=0;j<=P(K+1)-1;j++) { f[i][j]=0; for (int k=1;k<=K;k++) if ((d[k]&j)==d[k]) f[i][j]+=max(f[i+1][j],f[i+1][j|P(k)]+v[k]); else f[i][j]+=f[i+1][j]; f[i][j]/=(double)K; } printf("%.6lf\n",f[1][0]); }