zoukankan      html  css  js  c++  java
  • noip模拟赛 钻石

    分析:用裸暴力可以得60分,每次dfs,看第i个盒子到底有没有钻石就行了.其实这很像0/1背包问题,只是多了一个m的限制.这要怎么办呢?因为概率是可以加减的,所以可以先不考虑m的限制,求出概率,然后dfs一遍把money < m的概率给减掉就好了.

          正解是meet in the middle,dp+dfs跑的比正解还快.

     如果有的题多个限制不好处理,但是要求的东西满足线性性,那么可以先求出所有的情况的答案,然后把不满足限制的给减掉.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    int n, m, v[40], p[40];
    double f[40][40];
    
    void dfs(int dep, double gailv, int sum, int num)
    {
        if (sum >= m)
            return;
        if (dep == n + 1)
        {
            if (sum < m)
                f[n][num] -= gailv;
            return;
        }
        dfs(dep + 1, gailv * (double)p[dep] / 100, sum + v[dep], num);
        dfs(dep + 1, gailv * (double)(100 - p[dep]) / 100, sum, num + 1);
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
            scanf("%d%d", &v[i], &p[i]);
        f[1][0] = (double)p[1] / 100;
        f[1][1] = (double)(100 - p[1]) / 100;
        for (int i = 2; i <= n; i++)
            for (int j = 0; j <= i; j++)
            {
            if (j - 1 >= 0)
                f[i][j] += f[i - 1][j - 1] * (double)(100 - p[i]) / 100.0;
            f[i][j] += f[i - 1][j] * (double)p[i] / 100.0;
            }
        dfs(1, 1.0, 0, 0);
        for (int i = 0; i <= n; i++)
            printf("%.3lf
    ", f[n][i]);
    
        return 0;
    }
  • 相关阅读:
    Linux日常之命令sort
    Linux日常之命令sed
    Linux日常之命令grep
    Linux日常之命令awk
    Linux日常之命令tee
    Linux日常之数据重定向
    Hibernate打印SQL及附加参数
    使用D3 Geo模块画澳大利亚地图
    基于Spring-WS的Restful API的集成测试
    做项目时需要考虑的安全性问题
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7699353.html
Copyright © 2011-2022 走看看