08_Queue(队列UVa 10128)

问题描述:n(1<=n<=13)个身高均不相等的人站成一排,从左向右看能看见L个人,从右向左看能看见R个人,问这个队列有多少种排法?

问题分析:  1.n个人的身高可设为1~n,

       2.设dp[k][i][j]中,k代表当前有k个人的队列,i代表从左边看能看见的人数,j代表从右边看能看到的人数

       3.由于谁先进队列,谁后进队列无所谓,我们从最高的人开始排起,保证每次新加入队列的人都是队列里边最矮的一个。

       4.若将新加的人放在最左边,则dp[k][i][j] += dp[k-1][i-1][j];

          若将新加的人放在最右边,则dp[k][i][j] += dp[k-1][i][j-1];

          若将新加入的人放在中间的任意地方,则dp[k][i][j] += dp[k-1][i][j]*(k-2);

       所以状态转移方程为:dp[k][i][j] = dp[k-1][i-1][j] + dp[k-1][i][j-1] + dp[k-1][i][j]*(k-2);

例题链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1069

例题:UVa 10128

10128 - Queue

Time limit: 3.000 seconds

  There is a queue with N people. Every person has a di?erent heigth. We can see P people, when we are looking from the beginning, and R people, when we are looking from the end. Its because they are having di?erent height and they are covering each other. How many di?erent permutations of our queue has such a interesting feature?

Input
  The input consists of T test cases. The number of them (1<=T <=10000) is given on the rst line of the input file.

  Each test case begins with a line containing a single integer number N that indicates the number of people in a queue (1<=N<=13). Then follows line containing two integers.The first integer corresponds to the number of people, that we can see looking from the beginning.The second integer corresponds to the number of people, that we can see looking from the end.

Output
  For every test case your program has to determine one integer. Print how many permutations of N people we can see exactly P people from the beginning, and R people, when we are looking from the end.
Sample Input
3
10 4 4
11 3 1
3 1 2
Sample Output
90720
1026576
1

代码:

 1 #include "stdio.h"
 2 #include "string.h"
 3 #define N 15
 4 int dp[N][N][N];
 5
 6 int main()
 7 {
 8     int T;
 9     int n,L,R;
10     int i,j,k;
11     scanf("%d",&T);
12     memset(dp,0,sizeof(dp));
13     dp[1][1][1] = 1;
14     for(k=2; k<N; k++)
15     {
16         for(j=1; j<=k; j++)
17         {
18             for(i=1; i<=k-j+1; i++)
19                 dp[k][i][j] = dp[k-1][i][j]*(k-2) + dp[k-1][i-1][j] + dp[k-1][i][j-1];
20         }
21     }
22     while(T--)
23     {
24         scanf("%d %d %d",&n,&L,&R);
25         printf("%d\n",dp[n][L][R]);
26     }
27 }
时间: 2024-10-31 06:49:09

08_Queue(队列UVa 10128)的相关文章

ACM - 递推类题目总结

名曰递推实际上是一类DP计数问题. UVa 10081 -  Tight Words #include <iostream> #include <cstdlib> #include <cstdio> #include <algorithm> #include <cstring> #include <string> #include <vector> #include <cmath> #define mod 10

UVA 540(队列)

Description  Team Queue  Queues and Priority Queues are data structures which are known to most computer scientists. The Team Queue, however, is not so well known, though it occurs often in everyday life. At lunch time the queue in front of the Mensa

UVA Live Achrive 4327 Parade (单调队列,dp)

容易想到dp[i][j]表示在第i行j个路口的开始走最大高兴值. 每次可以向左走,或者向右边走,然后向北走.(或者直接往北) 向左走到,状态转移为dp[i][j] = dp[i][k] + happy[i][k][j](为了方便处理,i从1开始编号,0行dp值存0) 处理出前缀和,happy[i][k][j]表示为sum[i][j] - sum[i][k] 向左走应该取max(dp[i][k]-sum[i][k]) k应该满足time[i][k][j] <= k 随着j的变化k的范围是一个滑动窗

UVa 10935 Throwing cards away I【队列】

题意:给出 n张牌,从上往下编号依次为1到n,当牌的数目至少还剩下2张时,把第一张牌扔掉,然后把新的一张牌放在牌堆的最底部,问最后剩下的那一张牌是哪一张牌. 模拟队列的操作------- 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 usin

UVa 540 (团体队列) Team Queue

题意: 每个人都属于一个团体,在排队的时候,如果他所在的团体有人在队伍中,则他会站到这个团体的最后.否则站到整个队伍的队尾. 输出每次出队的人的编号. 分析: 容易看出,长队中,在同一个团体的人是排在一起的. 所以用两个队列模拟即可,一个队列保留团体的编号,另外一个队列数组存放的是团体中每个人的编号. 1 #include <cstdio> 2 #include <queue> 3 #include <map> 4 using namespace std; 5 6 co

UVA - 10588 Queuing at the doctors (队列)

Description Problem H: Queuing at the doctors Due to the increasing number of weird viruses spreading around, all the members of the International Confederation of Revolver Enthusiasts (ICORE) are required by their boss to do quarterly physical check

UVa 210 Concurrency Simulator (双端队列+模拟)

题意:给定n个程序,每种程序有五种操作,分别为 var = constant(赋值),print var (打印), lock, unlock,end. 变量用小写字母表示,初始化为0,为程序所公有(一个程序里对某个变量修改可以会影响其他程序里的这个变量), 常数小于100(也就是说最多两位数). 每个时刻都只能有一个程序处于运行状态,其他的都在等待,上述五种操作用时分别是t1, t2, t3, t4, t5.运行中的程序, 每次最多能运行q个时间,当q个时间被用完后,它会被放在等待队列的尾部,

UVa 540 Team Queue(团队队列)

题意  模拟团队队列的入队和出队 STL应用  用一个队列维护团队编号  再用一个队列数组维护个体 #include <cstdio> #include <cstring> #include <queue> #include <map> using namespace std; const int N = 1000005; int team[N]; int main() { int cas = 0, n, t, a; char cmd[20]; while(

UVA 12100 打印队列(STL deque)

题意: 给定n个优先级打印队列,然后从0开始编号到n-1.出队一个元素,如果他是队列中优先级最高的,打印(耗时一分钟),否则放到队尾(不耗时).给定一个m,求位置m的文件打印的时间. 分析: 用一个priority_queue去寻找优先级最高的元素,然后用一个deque<pair<int,int> >去模拟队列 pair第一个元素是优先级, 第二个是序号. 如果第一元素跟优先级相同,就出队,否则出队后插入队尾. (其实这题用queue也可以,不过deque好处是可以在队头插入,而且