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; }