zoukankan      html  css  js  c++  java
  • 【51nod1705】七星剑(成环DP)

    点此看题面

    大致题意: 你要把一把剑从0星升至7星,有n颗宝石供你选择,第i颗宝石的价值是c[i],用第i颗宝石将剑从k-1星升至k星的成功率是prob[k][i],而失败后会掉lose[k][i],要你求出将剑升至7星的期望花费。

    题解

    看到这题,自然而然地就会想到用动态规划来做,而转移方程其实也很好推:

    f[i]=min(f[i],f[i-1]+c[j]+(1-prob[i][j])*(f[i]-f[i-1-lose[i][j]));
    

    其中f[i]表示将剑升至i星的期望花费

    就这么简单?

    (But wait a minute...)

    在转移方程中左边和右边同时出现了(f[i])

    这就是传说中的成环(DP)

    那么成环(DP)该怎么做呢?

    其实在这道题目中有一个很简单的方法:移项。没错,就是我们初一上学期就接触过的移项。

    通过移项,原转移方程就变成了

    f[i]=min(f[i],(f[i-1]+c[j]-(1-prob[i][j])*f[i-1-lose[i][j]])/prob[i][j]);
    

    这样不就直接水过了吗!(顺便吐槽一下(N≤100)这样的数据范围真是太水了)

    代码

    #include<bits/stdc++.h>
    #define LL long long
    #define min(x,y) ((x)<(y)?(x):(y))
    #define N 100
    using namespace std;
    int n,c[N+5],lose[10][N+5];
    double prob[10][N+5],f[10];
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if(ch=='-') f=-1,ch=getchar();
    	while(ch>='0'&&ch<='9') (x*=10)+=ch-'0',ch=getchar();
    	return x*f;
    }
    int main(register int i,register int j,bool flag,bool ff)
    {
    	for(n=read(),i=1;i<=n;c[i++]=read());
    	for(i=1,ff=true;i<=7;(flag?0:ff=false),++i)
    		for(j=1,flag=false;j<=n;scanf("%lf",&prob[i][j]),flag|=prob[i][j++]>0.0);
    	if(!ff) return puts("-1"),0;//判断是否存在不可能的情况
    	for(i=1;i<=7;++i) 
    		for(j=1;j<=n;lose[i][j++]=read());
    	for(i=1;i<=7;++i)//DP过程,理解了再打真的很简单
    		for(f[i]=1e18,j=1;j<=n;++j) 
    			f[i]=min(f[i],(f[i-1]+c[j]-(1-prob[i][j])*f[i-1-lose[i][j]])/prob[i][j]);
    	return printf("%.8lf",f[7]),0;
    }
    
  • 相关阅读:
    矩阵快速幂
    快速排序
    用闭包来实现命令模式
    闭包和面向对象设计
    闭包及其作用
    阿里笔试
    如何在节点上添加样式
    getComputedStyle与currentStyle获取样式(style/class)
    今日头条笔试
    牛客网JavaScript编程规范
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/51nod1705.html
Copyright © 2011-2022 走看看