dp

BZOJ 4025: 二分图

岁酱吖の 提交于 2019-11-26 23:32:26
4025: 二分图 思路: 考虑按时间分治,然后把每条边按影响时间加入相应的区间(类似划分树)。然后考虑把包含每个叶子节点的边连起来,并判断有没有奇环。 由于分治时需要撤回某些并查集的合并操作,所以需要用到可撤销并查集。然后因为要判基环,所以又需要维护每个点到父亲节点的距离 \(dp[i]\) , 所以需要用到带权并查集。 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long #define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int>

Josephina and RPG(概率DP) ZOJ - 3735

北城余情 提交于 2019-11-26 20:48:35
题目    给出一个C(n, 3)阶的矩阵,每一阶代表一种角色,MAP【i】【j】是i能够打败j的概率,然后给出m个你需要去按顺序打败的对手。你可以随意选择起始角色,并可以在打败对手后选择是否换成对手的角色,问比到最后最大的胜率。 思想   定义dp【i】【j】数组,i代表打到第几个对手,j表示打完i后选择的人物。可以明显知道如果不进行角色替换的话,每种角色的转移是dp【i】【j】 = dp【i - 1】【j】* edge【j】【a】(a是第i个对手使用的角色)。在所有不变换角色的情况求完之后,那么变换成当前对手角色的最优情况也就是在所有不变情况中选择最好的。 #include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #include <stack> #include <map> #define ull unsigned long long #define met(a, b) memset(a, b, sizeof(a)) #define lowbit(x) (x&(-x)) #define MID (l + r) / 2 #define ll long long using

简单dp hdu2084数塔

老子叫甜甜 提交于 2019-11-26 19:52:56
Problem Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少? 已经告诉你了,这是个DP的题目,你能AC吗? Input 输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。 Output 对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。 Sample Input 1 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 Sample Output 30 ac代码 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn=1e3+10; int a[maxn][maxn],dp[maxn][maxn]; //其实可以用一个数组,两个数组方便理解 int main(){ int T; scanf("%d",&T); while(T--){ int n; scanf("%d",&n); for

景区路线规划(概率dp)

橙三吉。 提交于 2019-11-26 19:45:53
景区路线规划 题目描述 美团旅行团队最近打算推出一项新服务,为景区的各个景点规划游览路线,提升游客满意度。其中一个重要的问题是对于一个景区道路网,求出游客的满意度的期望值。基于用户的喜好差异,我们需要对男性游客和女性游客的满意度分别计算。 景区被描述成一张n个点、m条边的无向图(无重边,无自环)。每个点代表一个景点,第i个景点游览需要耗费ci分钟,会让男性游客和女性游客的满意度分别增加h1i和h2i(满意度初始值都为0)。每条边代表一条路,第i条边连接编号为xi,yi的两个景点,从景点xi走到yi和从yi走到xi的时间都是ti分钟。 每个游客在景区中最长可以游览k分钟,最开始会随机的通过不同大门进入到一个景点开始游览,每游览完一个项目,游客会等概率随机选择一个可以从当前景点直达且来得及游览的景点作为下一个游览目标(已经游览过的景点也会因为有各种新活动而让游客再次考虑,所以我们这里不区分景点是否已经游览过)。如果游览完一个景点后,周围没有来得及游览的景点,本次游玩就结束了。 请你分别计算小y和妹子在游玩结束后开心度的期望。 输入描述: 第一行给出三个空格隔开的整数,分别表示n, m, k(0 < n ≤ 100, 1 * 60 ≤ k ≤ 8 * 60) 接下来的n行,每行三个空格隔开的整数,分别表示ci, h1i, h2i (10 ≤ ci ≤ 60,0 < h1i, h2i ≤

区间dp专题练习

假如想象 提交于 2019-11-26 19:34:06
区间dp专题练习 题意 1.Equal Sum Partitions ? 这嘛东西, \(n^2\) 自己写去 \[\ \] \[\ \] 2. You Are the One 感觉自己智力被吊打 \(dp[i][j]\) 表示 , 对于当前的一个空栈 , \(i\) 到 \(j\) 这一段都出栈的最小花费 显然是长得一副区间 (诡) dp (异) 的样子 , 如何转移呢?(建议自己想想吧) 对于一个 \(dp[i][j]\) ,因为这个 \(i\) 必须是最先入栈的 , 所以我们可以枚举它的出栈时间 \(k\) , 那么总贡献就是 \[dp[i+1][k]+(k-i)*a[i]+sum[k+1..j] \cdot (k-i+1)\] 即先出栈的 \(i+1...k\) 的贡献和+i自己的贡献+ \(k+1..j\) 这一段的贡献和它们被推迟 \(k-i+1\) 位产生的贡献 rep(i,1,n) rep(j,i+1,n) dp[i][j]=1e9; rep(i,1,n) dp[i][i]=a[i]; drep(i,n,1) rep(j,i,n) rep(k,i,j) dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]+(k-i)*a[i]+(k-i+1)*(s[j]-s[k])); 来源: https://www.cnblogs.com

hdu 4870 Rating

心已入冬 提交于 2019-11-26 19:15:39
题意:给你两个初始分数为0的账号让你去打比赛,每场比赛赢的概率为 p ,赢了加50分,输了-100分,当然你不会负分,每次你会用分低的账号去打比赛,问你把一个账号打到1000分的需要参加比赛次数的期望值。 思路:网上都是说理所当然,反正这是我做的第二道概率dp我是想不出来,写这个博客是因为别人都没说清楚,我都不知道咋化简的,搞明白后我来写个详细的。 把50分当成1分,赢一把加1分数了-2。 dp【i】存的是从i-1分升到i分需要参加比赛次数的期望。如果赢的话,也就是打一场就到了,输的话分数变成了i-3,还得需要1 + dp[i-2] + dp[i-1] + dp[i]次才能到i分,因为就算输了,也是算参加了一次的,所以有这个1。 得到dp[i] = p*1 + (1-p)*( 1 + dp[i-2] + dp[i-1] + dp[i]); 把右边的dp[i]移项化简:dp[i] = 1/p + (1-p)/p*(dp[i-2] + dp[i-1]); 只用算出来dp[1] dp[2]就行了,dp[1]很明显是1/p, dp[2]和dp[i]差不多,但是分不会降到负数只会降到0。dp[2] = p*1 + (1-p)*(1+dp[1]+dp[2]), 化简就是dp[2] = 1/p/p; 因为每次会打分第的号,所以结果肯定是一个1000分,一个950分

掷骰子

荒凉一梦 提交于 2019-11-26 18:05:22
掷骰子 Problem Description 概率论的起源与赌博问题有关。16世纪,意大利的学者吉罗拉莫•卡尔达诺(Girolamo Cardano,1501——1576)开始研究掷骰子等赌博中的一些简单问题。17世纪中叶,当时的法国宫廷贵族里盛行着掷骰子游戏,游戏规则是玩家连续掷 4 次骰子,如果其中没有 6 点出现,玩家赢,如果出现一次 6 点,则庄家(相当于现在的赌场)赢。按照这一游戏规则,从长期来看,庄家扮演赢家的角色,而玩家大部分时间是输家,因为庄家总是要靠此为生的,因此当时人们也就接受了这种现象。那么现在让我们来计算一个概率问题。 一个骰子有n(4≤n≤8)个面,随机投掷m(1≤m≤32)次,请计算出现连续x个相同面的概率(C)。(结果请四舍五入到小数点后第3位。) Input 每行3个用空格分开的整数,分别表示n,m,x。 Output 每行一个数,表示概率C。 Sample Input 4 5 3 Sample Output 0.129 解释: 需要求抛 m次后,连续x次相同面的骰子的概率,我们可以分为一次一次的抛,那么第 i 次 和 第 i - 1 次的状况只有两种。 第一: 两次的点数相同, 那就是 1/n 第二:两次的点数不同,那就是 (n-1)/n 假设连续抛了10次,假设点数为字符,有可能为: AAABB CCC DD AAABC CDAAA AAABC

[ZJOI2008]骑士 题解

做~自己de王妃 提交于 2019-11-26 17:37:55
题目背景: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。 骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都 有且仅有一个 自己最厌恶的骑士(当然不是他自己),他是绝对 不会与自己最厌恶的人一同出征 的。 战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。 为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。(N<=1,000,000,骑士战斗力为不超过1,000,000的正整数)。 输入格式: 第一行包括一个正整数N,描述骑士团的人数。 接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。 题解:   根据题目的描述,每一个连通块里面有且仅有一个环,这些连通块就构成了一个 基环树森林

[LeetCode] 174. 地下城游戏

删除回忆录丶 提交于 2019-11-26 17:17:05
题目链接: https://leetcode-cn.com/problems/dungeon-game/ 题目描述: 一些恶魔抓住了公主(P)并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来拯救公主。 骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下,他会立即死亡。 有些房间由恶魔守卫,因此骑士在进入这些房间时会失去健康点数(若房间里的值为负整数,则表示骑士将损失健康点数);其他房间要么是空的(房间里的值为 0),要么包含增加骑士健康点数的魔法球(若房间里的值为正整数,则表示骑士将增加健康点数)。 为了尽快到达公主,骑士决定每次只向右或向下移动一步。 编写一个函数来计算确保骑士能够拯救到公主所需的最低初始健康点数。 示例: 例如,考虑到如下布局的地下城,如果骑士遵循最佳路径 右 -> 右 -> 下 -> 下,则骑士的初始健康点数至少为 7。 -2 (K) -3 3 -5 -10 1 10 30 -5 (P) 说明: 骑士的健康点数没有上限。 任何房间都可能对骑士的健康点数造成威胁,也可能增加骑士的健康点数,包括骑士进入的左上角房间以及公主被监禁的右下角房间。 思路: 这道题意思就是从左上角如何到右下角,只能向右,向下,在这之间有加血,有扣血

ZOJ 3735 Josephina and RPG (概率dp)

℡╲_俬逩灬. 提交于 2019-11-26 17:12:42
题意: 给你一个n,然后给你C(n,3)个队伍, 给你每个队伍之间的胜率。 接下来给你m个队伍,让你依次跟他们比赛,开始你能选择任意的队伍,如果你打赢了一支队伍,你可以选择换成输给你的这个队伍或者不换,你能随便选队伍,求完胜的最大概率(初始队伍让你随便选)。 思路:我们开个二维dp【 i 】【 j 】表示赢得前 i 个队伍后且当前的队伍是 j 的最大胜率。 #include <bits/stdc++.h> using namespace std; const int N = 1e4 + 5; double dp[N][200], ma[200][200]; int main() { int n; while( cin >> n){ int len = n*(n-1)*(n-2)/6; for(int i = 1; i <= len; i++){ dp[0][i] = 1; //初始化 for(int j = 1; j <= len; j++) cin >> ma[i][j]; } cin >> n; double x; for(int i = 1; i <= n; i++){ int pos; cin >> pos; pos++; x = 0; for(int j = 1; j <= len; j++){ dp[i][j] = dp[i-1][j] * ma[j][pos]; x