• Permutations 好题


     Permutations

    Time Limit: 20000/10000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
    SubmitStatus

    Problem Description

    给出两个正整数N、K,问存在多少个长度为N的排列,满足其峰顶数目为K。所谓排列就是有一个序列a[1] ...a[N],每个数均不相同,且都是1 

    <= a[i] <= N,a[i]是峰顶的意思是 a[i] > a[i - 1] && a[i] > a[i + 1],对于边界,我们假设a[0] = -1000000000 和 a[N + 

    1] = -1000000000

    Input

    多组数据,每组数据一行,N,K(1 <= N <= 10^18, 1 <= K <= 30)

    Output

    每组数据一行,你的答案 % 239

    Sample Input

    5 1
    5 2
    3 1
    10 3

    Sample Output

    16
    88
    4
    131

    Hint

    比如对于排列1 3 2 4 5,a[2] = 3和a[5] = 5都是峰顶,因此这个排列峰顶数目为2
     
     
      1 #include <iostream>
      2 #include <string.h>
      3 #include <algorithm>
      4 #include <math.h>
      5 #include <stdio.h>
      6 using namespace std;
      7 #define ll long long
      8 #define MAX 32
      9 #define mod 239
     10 struct matrix
     11 {
     12     int a[MAX][MAX];
     13 } origin,res,anss,ansa;
     14 matrix multiply(matrix x,matrix y)
     15 {
     16     matrix temp;
     17     memset(temp.a,0,sizeof(temp.a));
     18     int i,j,k;
     19     for(k=0; k<MAX; k++)
     20         for(i=0; i<MAX; i++)
     21             if(x.a[i][k])
     22                 for(j=0; j<MAX; j++)
     23                     temp.a[i][j]+=x.a[i][k]*y.a[k][j]%mod,temp.a[i][j]%mod;
     24     return temp;
     25 }
     26 void calc(ll x)
     27 {
     28     memset(res.a,0,sizeof(res.a));
     29     int i;
     30     for(i=0; i<MAX; i++)
     31         res.a[i][i]=1;
     32     while(x)
     33     {
     34         if(x&1)
     35             res=multiply(res,origin);
     36         origin=multiply(origin,origin);
     37         x>>=1;
     38     }
     39 }
     40 void init(int x)
     41 {
     42     memset(origin.a,0,sizeof(origin.a));
     43     int i,j;
     44     for(i=1; i<MAX; i++)
     45     {
     46         j=i-1;
     47         origin.a[i][i]=2*i;
     48         origin.a[i][j]=(x-2*j)%mod;
     49     }
     50 }
     51 int dp[241][241]= {0},ans;
     52 void init1()
     53 {
     54     int i,j;
     55     dp[1][1]=1;
     56     for(i=2; i<241; i++)
     57         for(j=1; j<i; j++)
     58             dp[i][j]=((dp[i-1][j]*2*j)%mod+(dp[i-1][j-1]*max(0,i-2*j+2))%mod)%mod;
     59 }
     60 int main()
     61 {
     62     init1();
     63     ll n,k,i,m,j,kk;
     64     while(~scanf("%lld%lld",&n,&k))
     65     {
     66         if(n<241)
     67         {
     68             printf("%d
    ",dp[n][k]);
     69             continue;
     70         }
     71         n-=239;
     72         ans=0;
     73         memset(anss.a,0,sizeof(anss.a));
     74         for(i=0; i<MAX; i++)anss.a[i][i]=1;
     75         for(kk=239; kk<478; kk++)
     76         {
     77             init(kk);
     78             anss=multiply(origin,anss);
     79             if((n%239)==(kk%239))
     80             {
     81                 for(i=0; i<MAX; i++)
     82                     for(j=0; j<MAX; j++)
     83                         ansa.a[i][j]=anss.a[i][j];
     84             }
     85         }
     86         n/=239;
     87         if(n)
     88         {
     89             for(i=0; i<MAX; i++)
     90                 for(j=0; j<MAX; j++)
     91                     origin.a[i][j]=anss.a[i][j];
     92             calc(n);
     93             ansa=multiply(ansa,res);
     94         }
     95         for(j=0; j<MAX; j++)
     96         {
     97             ans+=(dp[238][j]*ansa.a[k][j])%mod;
     98             ans%=mod;
     99         }
    100         printf("%d
    ",ans);
    101     }
    102 }
    View Code
  • 相关阅读:
    java 变量常量作用域
    简述Integer
    简述(非)静态代码块和构造方法的执行顺序
    父类子类在有(无)参构造方法继承的一些规则
    equals和==的区别
    创建和调用自定义类的方法简述
    int变量与double变量混合运算时的常见问题及方法
    int变量运算过程中的常见问题及方法
    初始Java
    Eclipse常用快捷键
  • 原文地址:https://www.cnblogs.com/ERKE/p/3868668.html
Copyright © 2020-2023  润新知