地精部落

2024-02-20 16:18
文章标签 部落

本文主要是介绍地精部落,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述 Description

    传说很久以前,大地上居住着一种神秘的生物:地精。 
    地精喜欢住在连绵不绝的山脉中。具体地说,一座长度为 N 的山脉 H可分为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到N 之间的正整数。 
    如果一段山脉比所有与它相邻的山脉都高,则这段山脉是一个山峰。位于边缘的山脉只有一段相邻的山脉,其他都有两段(即左边和右边)。 
    类似地,如果一段山脉比所有它相邻的山脉都低,则这段山脉是一个山谷。 
    地精们有一个共同的爱好——饮酒,酒馆可以设立在山谷之中。地精的酒馆不论白天黑夜总是人声鼎沸,地精美酒的香味可以飘到方圆数里的地方。 
    地精还是一种非常警觉的生物,他们在每座山峰上都可以设立瞭望台,并轮流担当瞭望工作,以确保在第一时间得知外敌的入侵。 
    地精们希望这N 段山脉每段都可以修建瞭望台或酒馆的其中之一,只有满足这个条件的整座山脉才可能有地精居住。 
    现在你希望知道,长度为N 的可能有地精居住的山脉有多少种。两座山脉A和B不同当且仅当存在一个 i,使得 Ai≠Bi。由于这个数目可能很大,你只对它除以P的余数感兴趣。

输入描述 Input Description

    输入仅含一行,两个正整数 N,P。 

输出描述 Output Description

输出仅含一行,一个非负整数,表示你所求的答案对P取余之后的结果。

样例输入 Sample Input

4 7

样例输出 Sample Output

3

数据范围及提示 Data Size & Hint

共有10 种可能的山脉,它们是: 
1324 1423 2143 2314 2413 
 
3142 3241 3412 4132 4231   
【数据规模和约定】 
对于 20%的数据,满足 N≤10; 
对于 40%的数据,满足 N≤18; 
对于 70%的数据,满足 N≤550; 
对于 100%的数据,满足 3≤N≤4200,P≤109   

评价:这道题是我看了题解以后才做出来的,真是一道神题,但是写题解的大神都不愿解释得太详细,所以我想了很久才想明白。。。看了题解以后真的觉得很像数的划分、约瑟夫问题还有国王游戏,代码出奇地简洁,但是思维量相当地高。
 题解:
三个引理:
 
①在n->n-1的转化过程中,我们删除了一个点后,我们可以将n-1个点视为仍是1~n-1的排列。
 
②在若排列Pn为一个合法抖动子序列,则交换i∈[1,n)与i+1,必能得到另一个抖动子序列。
 
③抖动序列的对称性,若存在第一段上升的长度为n的抖动子序列,则以n+1-x代x必能得到一个第一段下降的长度为n的抖动子序列。 

设f[i][j]为长度为i的,以j开头的,第一段下降的抖动子序列的个数,则循题意可得2*f[n+1][n+1]即为答案。

考虑转移:

①若j的下一个是j-1,则需要一个长度为n-1的,以j-1开头的上升子序列;

再分两种情况:

若j==n,则j-1为i-1中正数第一个数,所以可以转移到f[i][1];

若j<n,则j-1为i-1中正数第i-1-(j-1)+1-1个数,所以可转移到f[i-1][j-i].

我们根据状态设定,显然有f[i][0]=f[i][1]=0.

∴f[i][j]->f[i-1][j-i].

②若j的下一个不是j-1,则对于任意一个以j-1开头的下降子序列,均可以通过交换j-1和j+1得到。

∴f[i][j]->f[i][j-1]

综,f[i][j]=f[i-1][j-i]+f[i][j-1].

减少代码量?一个技巧:

改变状态,令f[i][j]=f[i+1][j+1],则初始状态变更为f[1][1]=1,i∈[1,n],j∈[1,n].
ps:这个题是2010年山东省赛第一轮第二试的第一题。。竟然如此蛋疼。。。。顿时感觉明年的省赛会很呵呵。。。 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include<iostream>  
  2. using namespace std;  
  3. #include<cstdio>  
  4. #include<cmath>  
  5. #include<algorithm>  
  6. #include<cstring>  
  7. int f[2][10001];  
  8. int main(){  
  9.     int n,p;  
  10.     bool tmp;  
  11.     scanf("%d%d",&n,&p);  
  12.     f[1][1]=1;  
  13.     for(int i=2;i<=n;++i){  
  14.         tmp=i&1;  
  15.         for(int j=1;j<=i;++j)  
  16.             f[tmp][j]=(f[!tmp][i-j+1]+f[tmp][j-1])%p;  
  17.     }  
  18.     printf("%d",(f[tmp][n]<<1)%p);  
  19.  

这篇关于地精部落的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/728797

相关文章

BZOJ 1821 [JSOI2010]Group 部落划分 Group 题解与分析

1821: [JSOI2010]Group 部落划分 Group Time Limit: 10 Sec   Memory Limit:64 MB Submit: 825   Solved: 386 Description 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则

python部落习题笔记

1----------- In [8]: x = 5In [9]: eval('x+1')Out[9]: ____ 答案:6 2------------divmod divmod(a,b):取a除以b的商和余数,功效等价于(a//b, a%b); 3------------enumerate enumerate:遍历列表时同时生成了序号,举个例子: 1

[JSOI2010]Group 部落划分 Group(最小生成树)

题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落之间则经常发生争斗。只是,这一切都成为谜团了——聪聪根本就不知道部落究竟是如何分布的。 不过好消息是,聪聪得到了一份荒岛的地图。地图上标注了N个野人居住的地点(可以看作是平面上的坐标)。我们知道,同一个部落的野人总是生活在附近。我们把两个部落的距离,

软件随想录:程序员部落酋长Joel谈软件(local.joelonsoftware.com/wiki)-10

给计算机系学生的建议 作:周思博 (Joel Spolsky) 译:Paul May 梅普华 校:Tian-Jian "Barabbas" Jiang 姜天戬 Sunday, January 02, 2005     虽然一两年前我就喊过 rich Windows GUI 用户端会是未来趋势,不过还是经常有大学生写电子邮件来问工作方面的建议,由于正逢招募时期,我想还是把我的标准建议写下

软件随想录:程序员部落酋长Joel谈软件(local.joelonsoftware.com/wiki)-8

8 学校只教Java的危险性 Thursday, December 29, 2005     懒惰的孩子。     辛勤工作这回事是怎么了?     一直发牢骚抱怨「现在的小孩」,怪他们不愿亦不能做较困难的事情,这显然表示我已逐渐老朽了。     你们很幸福啦,以前我们在化粪池里一个牛皮纸袋里住了三个月,早晨六点就得起床把袋子清干净,吃一块过期面包皮就开始工作(work

软件随想录:程序员部落酋长Joel谈软件(阮一峰译)-6

6. 经济利益驱动法   2006年8月9日,星期三     先讲一个笑话。19世纪的时候,在俄国的一个小村庄里,住着一个贫穷的犹太人。有一天,他遇到了一个骑着马的哥萨克人[①]。     “你用什么喂鸡?”哥萨克人问。     “就用一点面包屑。”犹太人回答。     “你好大的胆子,竟敢用这么低等的饲料喂俄国鸡!”哥萨克人说,拿起棍子打犹太人。     第二天,哥萨克人又来了。“

软件随想录:程序员部落酋长Joel谈软件(阮一峰译)-5

5. 军事化管理法   2006年8月8日,星期二     士兵应该害怕他们的长官,甚于害怕任何他们将要面对的危险……亲密永远不会让普通士兵面对危险时挺身而出,只有恐惧才会让他这样做。 ——腓特烈大帝[①]     命令和控制式的管理源于军事管理。大致上这种管理方法的思想是,人们只做你告诉他们去做的事情。如果他们没有做,你就对着他们吼,直到他们做了为止。如果他们还是不做,你就关他们的禁闭

软件随想录:程序员部落酋长Joel谈软件(阮一峰译)-3

3. 寻找优秀的程序员之实战指南      2006年9月7日,星期四     你是一个雇主。你在所有正确的地方刊登了招聘广告,你有一个完善的实习生制度,你面试了所有你想要的人。但是很不幸,如果优秀的程序员不愿意为你工作,你就无法把他们拉来工作。不要着急,现在就介绍如何使优秀程序员愿意为你工作。我将谈谈优秀的程序员想要什么,还有在工作环境中他们喜欢什么和不喜欢什么,以及如何使你的公司成为顶

软件随想录:程序员部落酋长Joel谈软件(阮一峰译)-2

2. 寻找优秀的程序员       2006年9月6日,星期三 优秀的程序员都在哪里 这是你第一次公开招募雇员。如同大多数人一样,你会发布广告,可能也会浏览一些大型的网上论坛,然后你就收到了一吨的简历。 一份份看下去,你会想:“嗯嗯嗯,这人应该可以。”或者:“这人差远了。”或者:“我要知道他能不能下决心搬到布法罗[①]来。”但是,我保证有一件事绝对不会发生,那就是你对自己说:“哇,这

软件随想录:程序员部落酋长Joel谈软件(阮一峰译)-1

1. 我的第一次BillG审查 2006年6月16日,星期五 早先,Excel[①]有一种没有名字的很蹩脚的编程语言。我们管它叫做“Excel宏语言”(Excel Macros)。这是一种功能很弱的编程语言,它没有变量(你不得不将值存在电子表格的单元格中),没有局部变量(local),没有子例程的调用(subroutine call);一句话,它的程序几乎无法维护。不过,它也有一些高级语言的特