首页 > 其他 > 详细

topcoder srm656 1000分题

时间:2015-04-21 22:44:08      阅读:483      评论:0      收藏:0      [点我收藏+]


Problem Statement

 

You are given an int N and a int[] pos. We are interested in some permutations of the set {1,2,...,N}. A permutation p is called good if the following condition is satisfied: for each valid k, we have p(k) < p(k+1) if and only if k is an element of pos.

Return the number of good permutations, modulo 1,000,000,007.

 

Definition

 
Class: PermutationCountsDiv2
Method: countPermutations
Parameters: int, int[]
Returns: int
Method signature: int countPermutations(int N, int[] pos)
(be sure your method is public)
 
 
 

Constraints

- N will be between 1 and 200, inclusive.
- pos will contain between 1 and N-1 elements, inclusive.
- Elements of pos will be distinct.
- Each element of pos will be between 1 and N-1, inclusive.
 

Examples

0)  
 
5
{3}
Returns: 9

Given that pos = {3}, we are looking for permutations where p(1) > p(2), p(2) > p(3), p(3) < p(4), and p(4) > p(5). Thus, the good permutations are the following ones:

  • {3,2,1,5,4}
  • {4,2,1,5,3}
  • {4,3,1,5,2}
  • {4,3,2,5,1}
  • {5,2,1,4,3}
  • {5,3,1,4,2}
  • {5,3,2,4,1}
  • {5,4,1,3,2}
  • {5,4,2,3,1}

Here, the notation {3,2,1,5,4} represents the permutation p for which p(1)=3, p(2)=2, p(3)=1, p(4)=5, and p(5)=4.

1)  
 
13
{12,11,10,9,8,7,6,5,4,3,2,1}
Returns: 1
2)  
 
13
{}
Returns: 1
3)  
 
9
{2,4,5}
Returns: 1421
4)  
 
80
{31,41,59,26,53,58,9,79,32,3,8,46}
Returns: 82650786

题目如上,也就是要求带有约束的permutation有多少种,有约束的时候p(k)<p(k+1),没有约束的时候p(k)>p(k+1), 鉴于topcoder里出题人写的代码中的注释有误,导致别人非常难理解,故在这里来把问题讲清楚一下。

我们用dp[i][j]表示处理前i个数,并以第j小的那个数最为第i个数时的方案总数,如果有约束的话,即第i-1个数要比第i个数小的话,那么dp[i][j] = sum(dp[i-1][k])(k<j),也就是前i-1个数中要取第k小的数作为第i-1个,这样才能保证p(i-1)<p(i),没有约束的话,即第i-1个数要比第i个数大的话,那么dp[i][j] = sum(dp[i-1][k])(k>=j),这里为什么k>=j而不是k>j,因为在i个数里面取出第j小的数x之后,前面i-1个数中第j小的数还是比 x要大的(原本排第j+1小的,因为第j小被取出了,故在前i-1个中排第j小了)初始化dp[1][1]表示一共1个数,以第1小的数作为结尾,那么当然只有一种方案。

所以代码如下:

#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
using namespace std;
bool g[10000];
int dp[220][220];
class PermutationCountsDiv2 {
public:
	int countPermutations(int N, vector <int> pos) {
		int mod = 1000000007;
		memset(g, 0, sizeof(g));
		for (int x : pos)
			g[x] = true;
		memset(dp, 0, sizeof(dp));
		dp[1][1] = 1;
		for (int i = 2; i <= N; i++)
		{
			for (int last = 1; last <= i; last++)
			{
				if (!g[i - 1])
				{
					for (int j = last; j <= i; j++)
						dp[i][last] = (dp[i][last] + dp[i - 1][j]) % mod;
				}
				else
				{
					for (int j = last - 1; j >= 1; j--)
						dp[i][last] = (dp[i][last] + dp[i - 1][j]) % mod;
				}
			}
		}
		int res = 0;
		for (int i = 0; i <= N; i++)
			res = (res + dp[N][i]) % mod;
		return res;


	}
};



topcoder srm656 1000分题

原文:http://blog.csdn.net/wangyuquanliuli/article/details/45175243

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!