oj练习---dp专题

1.POJ 3744  Scout YYF I

经典的dp模型,但是要用到快速矩阵幂加速,分段的思想 

# include <stdio.h>
# include <algorithm>
# include <string.h>
# include <iostream>
using namespace std;

int mines[15];

void matrixMulti(double a[2][2], double b[2][2]){
    double i,j,k,l;
    i = a[0][0]*b[0][0]+a[0][1]*b[1][0];
    j = a[0][0]*b[0][1]+a[0][1]*b[1][1];
    k = a[1][0]*b[0][0]+a[1][1]*b[1][0];
    l = a[1][0]*b[0][1]+a[1][1]*b[1][1];
    a[0][0]=i,a[0][1]=j,a[1][0]=k,a[1][1]=l;
}

double quickPow(const double p, int x){
    if(x == -1){
        return 1.0;
    }
    double a[2][2] = {0, 1, 1-p, p}, res[2][2] = {1,0,0,1};
    while(x){
        //printf("this 3\n");
        if(x&1){
            matrixMulti(res, a);
        }
        x/=2;
        matrixMulti(a,a);
    }
    return res[0][1]*(1-p);
}

int main(){
    int num;
    double p, result;
    while(scanf("%d%lf",&num, &p) != EOF){
        memset(mines, 0, sizeof(mines));
        for(int i = 1 ; i <= num; ++i){
            scanf("%d", mines + i);
        }
        if(mines[1] == 1){
            printf("%.7f\n", 0.0);
            continue;
        }
        mines[0] = 0;
        result = 1.0;
        sort(mines, mines+num+1);
        for(int i = 1; i <= num; ++i){
            result *= quickPow(p, mines[i] - mines[i - 1] - 1);
        }
        if(result < 0){
            result = 0;
        }
        if(result > 1){
            result =1;
        }
        printf("%.7f\n", result);
    }
    return 0;
}

心得:1.dp[i]=dp[i-2]*(1-p)+dp[i-1]*p,其实就是连续跟1-p/p相乘,自然想到矩阵加速。2.快速幂的思想,将O(n)降成O(lg(n))。

3.[0, 1; 1-p, p]  * [dp[i-2]; dp[i-1]] =  [dp[i-1]; dp[i]],然后变成幂运算之后就可以加速了。多次乘以相同的数值其实就是幂运算(一个数就是整数幂,多个数的式子就是矩阵幂)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值