http://acm.timus.ru/problem.aspx?space=1&num=1696

代码及其注释:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include <iomanip>
using namespace std;
#define LL long long
const int INF=0x3f3f3f3f;
const int N=1005;
const int M=205;
int ans[2][M][M];//ans[l][i][j] 把从1到n每个人的薪水看成一串数组
//到第l个人时最大值为i往后必须取值>=j时最优值
int a[M][M],b[M][M];//辅助数组可以降低时间复杂度
int main()
{
    //freopen("data.in","r",stdin);
    int n,k,p;
    while(cin>>n>>k>>p)
    {
        memset(ans,0,sizeof(ans));
        for(int i=1;i<=k;++i)
        ans[1][i][1]=1;//初始化
        for(int l=2;l<=n;++l)
        {
            for(int i=1;i<=k;++i)
            for(int j=1;j<=k;++j)
            {
                ans[l%2][i][j]=0;
                a[i][j]=(ans[(l-1)%2][i][j]+a[i-1][j])%p;
                b[i][j]=(ans[(l-1)%2][i][j]+b[i][j-1])%p;
            }
            for(int i=1;i<=k;++i)
            for(int j=1;j<=k;++j)
            {
                if(i==j&&j==1)//特判
                {ans[l%2][i][j]=1;continue;}
                if(j>=i)//特判
                {ans[l%2][i][j]=0;continue;}
                //在第 l 个人处加的值可以使 i (+a[i][j]) 也可以是 j (+b[i][j])
                ans[l%2][i][j]=(ans[l%2][i][j]+a[i][j]+b[i][j])%p;
            }
        }
        int sum=0;
        for(int i=1;i<=k;++i)
        for(int j=1;j<=k;++j)
        sum=(sum+ans[n%2][i][j])%p;
        cout<<(sum+1)<<endl;
    }
    return 0;
}

  

posted on 2013-03-04 19:05  夜->  阅读(411)  评论(0编辑  收藏  举报