【BZOJ1076】【SCOI2008】奖励关

题目大意

  每件物品等概率出现,有条件选择,求最优策略下期望概率。


Solution

  首先,看完题目和数据范围,可以知道这是一个期望DP。我一开始从前往后推,然后发现怎么都推不出来,卡了半天……TAT。
  原因在于,后面可能的状态会影响前面的选择,每一次的选择都跟后面可能的状态和前面的状态有关。那么如果倒着推,对于一定的状态来说,后面的最优策略已经确定,只要枚举前面所有可能的状态,判断每个后继状态最优的答案。这样,虽然有一部分计算是冗余的(即不可能出现),但在计算过程中只会把需要的部分加入答案。
  

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define rep(i,a,b) for (int i=a; i<=b; i++)
#define per(i,a,b) for (int i=a; i>=b; i--)
using namespace std;
typedef long long LL;

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;
}

const int N = 105;
const int M = 1<<15;
const int C = 15;

int K,n;
int val[C],need[C];
double dp[N][M],P;

int main() {

    #ifndef ONLINE_JUDGE
    //  freopen("data.in","r",stdin);
    //  freopen("data.out","w",stdout);
    #endif

    K=read(),n=read();
    rep(i,0,n-1) {
        val[i]=read(); int sta=0;
        while (true) {
            int x=read(); x--;
            if (x==-1) break;
            sta|=(1<1.0/n;
    per(i,K-1,0) {
        rep(j,0,(1<1) {
            rep(k,0,n-1) {
                if ((need[k]&j)==need[k]) dp[i][j]+=max(dp[i+1][j|(1<1][j])*P;
                else dp[i][j]+=dp[i+1][j]*P;
            }
        }
    }

    printf("%.6lf\n",dp[0][0]);

    return 0;
}

你可能感兴趣的:(BZOJ,动态规划)