SGU489

来源:互联网 发布:特征匹配算法 labview 编辑:程序博客网 时间:2024/06/05 12:47

不知道是什么原因,别人的o(n^2)是600ms,我的却是900ms擦边过。这个题的状态方程如下:dp[i][j][0]=sigma(dp[i-1][x][1])(j<=x<=i-1)  dp[i][j][1]=sigma(dp[i-1][x][0])(1<=x<=j-1)其中最后的状态0,1分别表示最后是高低还是低高。其中i表示的是现在有多少位数,j表示的是最后一位是什么。这个状态方程是硕神告诉的。之前想了很久都没有想出来。这样想的。。当最后一位为j的时候,序列是0状态下的。。那意思是前面的那一位数会高于后面的那一位。因为最后一位为j那么就相当于将n与j交换。但是这个交换不是简单的交换。而是将之前只有n-1位的时候大于等于j的数都加一。。那么就将n换到序列里面了。所以在0状态的时候就是前面的>=j的所有可能的和。同理可以推出1状态的情况。

但是这个dp需要一些小地方注意优化。。减少时间什么的。

上代码:

#include<cstdio>
using namespace std;
int dp[4][10010][2];
main(){
    int  n;
    int m;
    scanf("%d%d",&n,&m);
    dp[1][1][0]=1;dp[1][1][1]=1;
    for(int i=2;i<=n;i++){
        for(int j=1;j<=i;j++){
            dp[i%2][j][0]=0;
            dp[i%2][j][1]=0;
        }
        for(int j=1;j<=i;j++){
                dp[i%2][j][0]+=((dp[(i-1)%2][i-1][1]-dp[(i-1)%2][j-1][1])+m)%m;
                dp[i%2][j][1]+=dp[(i-1)%2][j-1][0];
        }
        for(int j=2;j<=i;j++){
            dp[i%2][j][0]+=dp[i%2][j-1][0];
            dp[i%2][j][0]=dp[i%2][j][0]%m;
            dp[i%2][j][1]+=dp[i%2][j-1][1];
            dp[i%2][j][1]=dp[i%2][j][1]%m;
        }
    }
    int ans=0;
    ans=(dp[n%2][n][0]+dp[n%2][n][1])%m;
    if(n==1)
        ans=1;
    printf("%d\n",ans%m);
}

原创粉丝点击