zoukankan      html  css  js  c++  java
  • [bzoj4832][Lydsy1704月赛]抵制克苏恩

    题目大意:有一个英雄和若干个所从,克苏恩会攻击$K$次,每次回随机攻击对方的一个人,造成$1$的伤害。现在对方有一名克苏恩,你有一些随从。如果克苏恩攻击了你的一名随从,若这名随从不死且你的随从数量不到$7$,这名随从会召唤一个拥有$3$点血的新随从(血量到$0$时会死亡)。已知克苏恩攻击次数,场上一血,二血,三血的随从数量,问英雄收到的伤害点数的期望。

    题解:$f_{i,j,k,l}$表示还可以攻击$i$下,一血随从$j$个,二血随从$k$个,三血随从$l$个时英雄收到伤害的期望。

    $$f_{i,j,k,l}=frac{f_{i-1,j,k,l}+1+f_{i-1,j-1,k,l} imes j+f_{i-1,j+1,k-1,l+check} imes  k+f_{i-1,j,k+1,l-1+check} imes l}{j+k+l+1}\(check为求出场上随从个数,<7返回1,否则返回0)$$

    卡点:1.看成了每个随从都会召唤随从

    C++ Code:

    #include <cstdio>
    #include <cstring>
    using namespace std;
    int Tim, k, a, b, c;
    double f[55][8][8][8];
    bool v[55][8][8][8];
    int check(int a, int b, int c) {
    	int tmp = a + b + c;
    	if (tmp < 7) return 1;
    	return 0;
    }
    double dfs(int k, int a, int b, int c) {
    	if (k <= 0) return 0;
    	if (a < 0 || b < 0 || c < 0) return 0;
    	if (v[k][a][b][c]) return f[k][a][b][c];
    	double &ans = f[k][a][b][c];
    	ans = dfs(k - 1, a, b, c) + 1;
    	ans = ans + dfs(k - 1, a - 1, b, c) * a;
    	ans = ans + dfs(k - 1, a + 1, b - 1, c + check(a, b, c)) * b;
    	ans = ans + dfs(k - 1, a, b + 1, c - 1 + check(a, b, c)) * c;
    	ans = ans / (a + b + c + 1);
    	v[k][a][b][c] = true;
    	return ans;
    }
    int main() {
    	scanf("%d", &Tim);
    	while (Tim--) {
    		scanf("%d%d%d%d", &k, &a, &b, &c);
    		printf("%.2lf
    ", dfs(k, a, b, c));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    浅谈 Web 缓存
    纯前端实现人脸识别-提取-合成
    正则表达式对金额的处理函数
    算法设计题怎么复习
    leetcode 446 等差数列划分 II
    git远程分支关系、命令
    深度优先遍历DFS--用简单的方式理解
    数据结构程序题
    常用排序算法的时间复杂度和空间复杂度
    英语句子
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9472536.html
Copyright © 2011-2022 走看看