Find the Marble(线性dp/概率dp)

https://cn.vjudge.net/problem/ZOJ-3605

Alice and Bob are playing a game. This game is played with several identical pots and one marble. When the game starts, Alice puts the pots in one line and puts the marble in one of the pots. After that, Bob cannot see the inside of the pots. Then Alice makes a sequence of swappings and Bob guesses which pot the marble is in. In each of the swapping, Alice chooses two different pots and swaps their positions.

Unfortunately, Alice's actions are very fast, so Bob can only catch k of m swappings and regard these k swappings as all actions Alice has performed. Now given the initial pot the marble is in, and the sequence of swappings, you are asked to calculate which pot Bob most possibly guesses. You can assume that Bob missed any of the swappings with equal possibility.
Input

There are several test cases in the input file. The first line of the input file contains an integer N (N ≈ 100), then N cases follow.

The first line of each test case contains 4 integers n, m, k and s(0 < s ≤ n ≤ 50, 0 ≤ k ≤ m ≤ 50), which are the number of pots, the number of swappings Alice makes, the number of swappings Bob catches and index of the initial pot the marble is in. Pots are indexed from 1 to n. Then m lines follow, each of which contains two integersai and bi (1 ≤ ai, bi ≤ n), telling the two pots Alice swaps in the i-th swapping.
Outout

For each test case, output the pot that Bob most possibly guesses. If there is a tie, output the smallest one.
Sample Input

3
3 1 1 1
1 2
3 1 0 1
1 2
3 3 2 2
2 3
3 2
1 2

Sample Output

2
1
3
一共有 n 个杯子,有一个石头开始是放在第 s 号杯子里,然后交换这些杯子 m 次,但是只能记住其中的 k 次,每次交换没有看到交换的概率相同,求最终猜的那个人最可能猜的是哪号杯子里有石头。

dp[i][j][k]代表交换了i次,看到了j次,石子在k位置

https://blog.csdn.net/u012860063/article/details/45199239

#include<bits/stdc++.h>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
ll dp[55][55][55];
int a[55],b[55]; 
int n,m,k,s;
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
    	scanf("%d%d%d%d",&n,&m,&k,&s);
    	memset(dp,0,sizeof(dp));
    	dp[0][0][s]=1;
    	for(int i=1;i<=m;i++){
    	    scanf("%d%d",&a[i],&b[i]);
	}
	for(int i=1;i<=m;i++){
	    dp[i][0][s]=1;
	    for(int j=1;j<=min(i,k);j++){
		dp[i][j][a[i]]=dp[i-1][j-1][b[i]];//看到石子交换
		dp[i][j][b[i]]=dp[i-1][j-1][a[i]];
		for(int p=1;p<=n;p++) {	//没看到石子交换
		    dp[i][j][p]+=dp[i-1][j][p];//没看到交换
		    if(p!=a[i]&&p!=b[i]) //看到交换,但没石子 
		    dp[i][j][p]+=dp[i-1][j-1][p];
		}
	     }
	}
	int ans=1;
        for(int i=2;i<=n;i++){
            if(dp[m][k][i]>dp[m][k][ans]) ans=i;
	} 
	printf("%d\n",ans);
    }
    return 0;
} 

 

全部评论

相关推荐

12-24 20:52
武汉大学 Java
点赞 评论 收藏
分享
12-08 07:42
门头沟学院 Java
27届末九,由于是女生,身边人几乎没有就业导向的,自学只能跟着网课,没人指导,很迷茫。下图是我目前的简历,不知道有需要修改的地方吗?求拷打。下面是目前的学习情况:目前算法过完了一遍力扣100和代码随想录,不过不是很熟,面经看了小林coding、JavaGuide,有一些没用过的技术看得不是很明白,掌握得不是很扎实。再加上常年跟黑马网课听思路,真正自己动手写代码的时间很少,这让我一直不敢投简历,总觉得内里空虚。项目没准备好面试相关的问题,简历上相应的考点不熟。如此种种。。。看到很多很多学长学姐大佬们的面经,愈发觉得面试可怕,自己没准备好,总担心自己是不是无望后端开发了。看到牛客很多同届以及更小一届的同学都找到实习了,很希望自己也能找到实习。而自己又好像摸不到后端学习的门路,只能不断赞叹黑马虎哥写的代码真优雅!微服务架构实在巧妙!消息队列、redis、sentinel、nacos、mybatisplus等等的引入都会让我赞叹这些工具的设计者的巧思,以及包括但不限于Java语言的优雅。然而只是停留在了解的程度,并不熟练。我是很希望能够继续深入探索这些知识的,只不过有一大部分时间都花在学校课程上了。我感觉我被困住了,我一方面必须保证我能够有个不错的学业分使我能有我几乎不想选择的读研退路(还有个原因是复习不全我会焦虑考试挂科,因此我会做好全面的准备,而这一步很费时间),一方面在B站学习各种网课,一方面得考虑提升自己并不扎实的算法基础,另一方面还得准备八股面经。这让我有点苦恼,我好像没那么多时间,因为绝大部分时间都花在了复习学校科目中了。我好像处处用时间,但收效甚微。想问问各位大佬是怎么平衡时间的呢?算法、项目和八股是怎么准备的呢?有什么高效的方法吗?谢谢您们花时间阅读我的稿件!
菜菜狗🐶:大胆投,我当时也是害怕面试,投多了发现根本约不到面🤡
投递哔哩哔哩等公司6个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务