读书笔记 -- 动态规划 + 离散化

半夜睡不着,起来看看书,就看到了这题,费了大半个小时才看明白,然后不困了Orz。

书上都有代码,但是为什么我再敲一遍。如果没明白我是不会抄一遍的,那样没有意义。

看到能给我启发的题目,我觉得还是记录下来比较好,毕竟0-1背包,自己还没有写过小数版的Orz。

本来也不怎么会说,还不如课本说的清楚。直接截图吧。

状态转移方程:

从后往前推:dp[i][j] 表示第还剩i轮次,当前的金币数为j。

设第i次的选择是拿出k当作赌注,那么输了概率是1-p,最后的钱是j-k,如果赢了,最后的钱是j+k,

那么作为金钱数j的当前轮次所能赢的最终钱的概率的最优选择是最合适的k,让他的概率最高。

dp[i][j] =max{ dp[i-1][j+k]*p + dp[i-1][j-k]*(1-p)}

使用滚动数组来节省内存,不过不用也应该是可以的,M最大是16

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
typedef long long LL;
const int MAXM = 16;

double dp[2][1 << MAXM | 1];
int  M, X;
double P;
void solve()
{
    memset(dp, 0, sizeof(dp));
    int n = 1 << M;
    dp[0][n] = 1.0;

    for(int r = 1; r <= M; r++)
    {
        for(int i = 0; i <= n; i++)
        {
            double t = 0.0;
            int duzhu = min(i, n - i);
            for(int j = 0; j <= duzhu; j++)
            {
                t = max(t, P * dp[!(r & 1)][i + j] + (1 - P) * dp[!(r & 1)][i - j]);
            }
            dp[r & 1][i] = t;
        }
    }
    int x = (LL)X * n / 1000000;
    printf("%.6f\n", dp[M & 1][x]);
}

int main()
{
    scanf("%lf%d%d", &P, &X, &M);
    solve();
    return 0;
}
时间: 2024-10-13 10:21:14

读书笔记 -- 动态规划 + 离散化的相关文章

读书笔记--大规模web服务开发技术

总评   这本书是日本一个叫hatena的大型网站的CTO写的,通过hatena网站从小到大的演进来反应一个web系统从小到大过程中的各种系统和技术架构变迁,比较接地气. 书的内容不是很难,所以总的来说比较容易阅读,不需要特别累的啃,可想而知,不是非常深入的,更多的还是把作者的一些经验写出来,hatena这种量级的在国内应该是一个中型网站的水平,作者基本把这个量级web服务的运维的方方面面都讲了一遍,看完可以对这个这种量级网站有一个总体的了解,个人认为还是值得一读的. 逐章读书笔记: 第一章 大

算法导论读书笔记之钢条切割问题

算法导论读书笔记之钢条切割问题 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 给定一段长度为n英寸的钢条和一个价格表 pi (i=1,2, -,n),求切割钢条的方案,使得销售收益rn最大.注意,如果长度为n英寸的钢条价格pn足够大,最优解可能就是完全不需要切割. 若钢条的长度为i,则钢条的价格为Pi,如何对给定长度的钢条进行切割能得到最大收益? 长度i   1   2    3   4     5      6     7     8  

《Linux/Unix系统编程手册》读书笔记8 (文件I/O缓冲)

<Linux/Unix系统编程手册>读书笔记 目录 第13章 这章主要将了关于文件I/O的缓冲. 系统I/O调用(即内核)和C语言标准库I/O函数(即stdio函数)在对磁盘进行操作的时候都会发生缓冲.通过缓冲可以在一定程度上将用户空间与实际的物理设备分离,还可以减少内核访问磁盘的次数. 先来看看关于内核缓冲区高速缓冲:read和write调用在对磁盘文件进行操作的时候不会直接访问磁盘,如下图所示. 例如:write(fd, "abc", 3) write调用会将"

算法导论读书笔记(17)

算法导论读书笔记(17) 目录 动态规划概述 钢条切割 自顶向下的递归实现 使用动态规划解决钢条切割问题 子问题图 重构解 钢条切割问题的简单Java实现 动态规划概述 和分治法一样, 动态规划 (dynamic programming)是通过组合子问题的解而解决整个问题的.分治法是将问题划分成一些独立的子问题,递归地求解各子问题,然后合并子问题的解而得到原问题的解.与此不同,动态规划适用于子问题并不独立的情况,即各子问题包含公共的子子问题.在这种情况下,分治法会重复地求解公共的子子问题.而动态

算法导论读书笔记(18)

算法导论读书笔记(18) 目录 最长公共子序列 步骤1:描述最长公共子序列的特征 步骤2:一个递归解 步骤3:计算LCS的长度 步骤4:构造LCS LCS问题的简单Java实现 最长公共子序列 某给定序列的子序列,就是将给定序列中零个或多个元素去掉后得到的结果.其形式化定义如下:给定一个序列 X = < x1 , x2 , - , xm >,另一个序列 Z = < z1 , z2 , - , zk >,如果 Z 满足如下条件则称 Z 为 X 的 子序列 (subsequence),

《算法导论》读书笔记(七)

前言:贪心算法也是用来解决最优化问题,将一个问题分成子问题,在现在子问题最优解的时,选择当前看起来是最优的解,期望通过所做的局部最优选择来产生一个全局最优解.书中先从活动选择问题来引入贪心算法,分别采用动态规划方法和贪心算法进行分析.本篇笔记给出活动选择问题的详细分析过程,并给出详细的实现代码进行测试验证.关于贪心算法的详细分析过程,下次在讨论. 1.活动选择问题描述   有一个需要使用每个资源的n个活动组成的集合S= {a1,a2,···,an },资源每次只能由一个活动使用.每个活动ai都有

《C#图解教程》读书笔记之三:方法

本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.方法那些事儿 (1)方法的结构:方法头-指定方法的特征,方法体-可执行代码的语句序列: (2)方法的调用:参数.值参数.引用参数.输出参数.参数数组: ①参数: 形参-本地变量,声明在参数列表中:形参的值在代码开始之前被初始化: 实参-实参的值用于初始化形参: ②值参数: 为形参在栈上分配内存,将实参的值复制到形参: ③引用参数: 不为形参在栈上分配内存,形参的参数名作为实参变量的别名指向同一位置,必须使用ref关

《C#图解教程》读书笔记之五:委托和事件

本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.委托初窥:一个拥有方法的对象 (1)本质:持有一个或多个方法的对象:委托和典型的对象不同,执行委托实际上是执行它所"持有"的方法.如果从C++的角度来理解委托,可以将其理解为一个类型安全的.面向对象的函数指针. (2)如何使用委托? ①声明委托类型(delegate关键字) ②使用该委托类型声明一个委托变量 ③为委托类型增加方法 ④调用委托执行方法 (3)委托的恒定性: 组合委托.为委托+=增加

《Effective C++》读书笔记汇总

我之前边读<Effective C++>边写下每个条款的读书笔记,这一版是C++11之前的版本.这里我将每个条款令我印象深刻的点小结一下. 1.C++包括:Plain C(面向过程).OOP(面向对象).模板(泛型和模板元编程).STL(C++标准库). 2.用inline.enum.const代替#define.#define定义的宏,一旦复杂起来,高手都很难掌控.不要带入C的习惯. 3.灵活使用const前缀.不需要进行改变的数据加上const前缀.指针的const前缀有两种形式,cons