URAL 1260

题目大意:给1-N个数排序,要求相邻的数的差不能大于2,求对应的排序方法(1必须在第一个)。

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

数据规模:1<=N<=55。

理论基础:无(好久没有学新理论了,因为这些题都不需要)。

题目分析:ans[i]表示N=i时的答案。那么ans[i]=

1.(1,2,...)=ans[i-1](把1去掉,后面的数每个都减去1)。

2.(1,3,2,4,...)=ans[i-3](把1,3,2去掉,后面每个数都减去1)。

3.(1,3,5,...,最大的奇数,最大的偶数,...,4,2)=1。(3后面不可能接2(与情况2相同)和4(5(下来接2)或者2(下来接5)就不可能有了),所以3后面只能接5,5同3依次类推)。

综上:ans[i]=ans[i-1]+ans[i-3]+1=ans[i-1]+ans[i-2]-ans[i-5]。

打表(不打也不会超,N太小),O(1)。

代码如下:


  
  
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <ctime>
#include <vector>
using namespace std ;
typedef double db ;
#define DBG 0
#define maa ( 1 << 31 )
#define mii (( 1 << 31 )- 1 )
#define ast ( b ) if ( DBG && !( b )) { printf ( "%d!!| \n " , __LINE__ ); while ( 1 ) getchar (); } //调试
#define dout DBG && cout << __LINE__ << ">>| "
#define pr ( x ) #x "=" << ( x ) << " | "
#define mk ( x ) DBG && cout << __LINE__ << "**| " #x << endl
#define pra ( arr , a , b ) if ( DBG ) { \
dout <<#arr "[] |" <<endl ; \
for ( int i =a ,i_b =b ;i <=i_b ;i ++) cout << "[" <<i << "]=" <<arr [i ]<< " |" <<((i -(a )+ 1 )% 8 ? " " : " \n " ); \
if ((b -a +1 )% 8 ) puts ( "" );\
}
template < class T > inline bool updateMin ( T & a , T b ) { return a > b ? a = b , true : false ; }
template < class T > inline bool updateMax ( T & a , T b ) { return a < b ? a = b , true : false ; }
typedef long long LL ;
typedef long unsigned int LU ;
typedef long long unsigned int LLU ;
int cnt , N ;
int ans [ 56 ]= { 0 , 1 , 1 , 2 , 4 , 6 , 9 , 14 , 21 , 31 , 46 , 68 , 100 , 147 , 216 , 317 , 465 , 682 , 1000 , 1466 ,
2149 , 3150 , 4617 , 6767 , 9918 , 14536 , 21304 , 31223 , 45760 , 67065 , 98289 , 144050 , 211116 ,
309406 , 453457 , 664574 , 973981 , 1427439 , 2092014 , 3065996 , 4493436 , 6585451 , 9651448 ,
14144885 , 20730337 , 30381786 , 44526672 , 65257010 , 95638797 , 140165470 , 205422481 ,
301061279 , 441226750 , 646649232 , 947710512 , 1388937263 } ;
int main ()
{
if (DBG )
{
for ( int i = 5 ;i <= 55 ;i ++)
{
ans [i ]=ans [i -1 ]+ans [i -2 ]-ans [i -5 ];
printf ( ",%d" ,ans [i ]);
}
}
else while (~ scanf ( "%d" ,&N )) printf ( "%d \n " ,ans [N ]);
return 0 ;
}

没有其中了、、、

by:Jsun_moon http://blog.csdn.net/jsun_moon


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值