A题
//dp思想,也可以用递推思想,用a[i][j]表示有多少钟方法到(i,j)所以前一步肯定式(i-1,j)或(i,j-1)所以到达(i,j)就有a[i-1][j]+a[i][j-1]种
//a[i][0] = 1;a[0][i] = 1;
//然后不断从左上往右下递推过去
#include<bits/stdc++.h>
using namespace std;
const int maxn = 35;
long long a[maxn][maxn];
int main()
{
for(int i = 0;i < maxn;i++)a[i][0] = 1,a[0][i] = 1;
for(int i = 1;i <maxn;i++){
for(int j = 1;j < maxn;j++){
a[i][j] = a[i][j-1] + a[i-1][j];
}
}
int n,m;
while(~scanf("%d%d",&n,&m)&&(n+m)){
printf("%I64d\n",a[n][m]);
}
}
B题
//首先k个全部错排有错排公式 d[i] = (i-1)(d[i-1) + d[i-2]);
//如果最后一个错排前n-1件有k-1件错排那个最后一个也要错排,如果后一个不用错排前N-1件k件错排,也就是杨辉三角c[i][j] = c[i-1][j-1]+c[i-1][j]
//然后两者乘积即是答案
#include<cstdio>
using namespace std;
const int N = 1001;
const int mod = 1000000007;
#define ll long long
ll d[N], c[N][N];
int main() {
d[2] = 1;
for(int i = 3; i < N; i ++)
d[i] = (i - 1) * (d[i-1] + d[i-2]) % mod;
//求组合数
for(int i = 1; i < N; i ++)
c[i][0] = c[i][i] = 1;
for(int i = 2; i < N; i ++)
for(int j = 1; j < i; j ++)
c[i][j] = (c[i-1][j-1] + c[i-1][j]) % mod;
int n, k;
while(~scanf("%d%d", &n, &k), n + k){
if(k==0){puts("1");continue;}
printf("%I64d\n", d[k] * c[n][k] % mod);
}
return 0;
}
C题
//斐波那契额
#include<bits/stdc++.h>
using namespace std;
int a[50];
int main(){
a[1] = 2;
a[2] = 3;
for(int i = 3;i <= 40;i++){
a[i] = a[i-1] + a[i-2];
}
int n;
while(~scanf("%d",&n)&&n){
printf("%d\n",a[n]);
}
}
D题
//a[n] = a[n-1] + a[n-2] + 2^(n-2)
//前n-1位满足n位肯定可以,当倒数第二位为0时有a[n-2]种,当倒数第1,2是11时前n-2位就可以随便拍
#include<stdio.h>
#include<string.h>
#define mod 1000000007
#define m 1000001
int a[m];
int p[m];
int main()
{
int i,j;
p[0]=0;p[1]=0;p[2]=1;
for(i=3;i<m;i++)
p[i]=p[i-1]*2%mod;
a[1]=0;a[2]=1;a[3]=3;
for(i=4;i<m;i++)
a[i]=((a[i-1]+a[i-2])%mod+p[i])%mod;
scanf("%d",&j);
while(j--)
{
int n;
scanf("%d",&n);
printf("%d\n",a[n]);
}
}
E题
//你要算出从0到i段的L的数量,LO的数量,LOV的数量,LOVE的数量。假设dp[i][1]表示0到i这一段字符串中LO的数量,那么在0到i+1段中的LO有两种,一种是LO完全位于0到i段,另一种是L位于前i段,O位于i+1处。这样就可以递推了。其它类似
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
const int maxn = 1001;
int dp[maxn][4];
char s[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
int len = strlen(s);
memset(dp,0,sizeof(dp));
if(s[0] == 'L')dp[0][0] = 1;
for(int i = 1;i < len ;i++){
dp[i][0] = dp[i-1][0];
dp[i][1] = dp[i-1][1];
dp[i][2] = dp[i-1][2];
dp[i][3] = dp[i-1][3];
if(s[i] == 'L'){dp[i][0] = (dp[i-1][0]+1)%mod;}
if(s[i] == 'O'){dp[i][1] = (dp[i-1][1]+dp[i-1][0])%mod;}
if(s[i] == 'V'){dp[i][2] = (dp[i-1][2]+dp[i-1][1])%mod;}
if(s[i] == 'E'){dp[i][3] = (dp[i-1][3]+dp[i-1][2])%mod;}
}
printf("%d\n",dp[len-1][3]);
}
return 0;
}
F题
//n=1时:m
//n=2时:m*(m-1)
//n=3时:m*(m-1)*(m-2)
//n>3时:
//若n-1与1颜色不同,则f[n-1]是排列好的,n号方块有m-2种颜色可涂 f[n]+=f[n-1]*(m-2)
//若n-1与1颜色相同,则f[n-2]是排列好的,n号方块有m-1种颜色可涂 f[n]+=f[n-2]*(m-1)
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MOD=1000003;
int m,n;
long long int f[3000];
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(f,0,sizeof(f));
f[1]=m;f[2]=m*(m-1)%MOD;f[3]=m*(m-1)*(m-2)%MOD;
if(n>3)
for(int i=4;i<=n;i++)
{
f[i]=(f[i-1]*(m-2)%MOD+f[i-2]*(m-1)%MOD)%MOD;
}
printf("%d\n",f[n]%MOD);
}
return 0;
}
G题
//暴力左子树节点的个数 然后递推
#include<stdio.h>
#define N 101
#define MOD 1000000007
int main()
{
long long s[N];
int i,j,n;
s[0] = 1;
for(i=1;i<=100;i++)
{
s[i]=0;
for(j=0;j<i;j++)
{
n=s[j]*s[i-j-1]%MOD;
s[i]+=n;
}
s[i]%=MOD;
}
while(scanf("%d",&n)!=EOF&&n!=-1)
{
printf("%I64d\n",s[n]);
}
}
H题
//奇数无解 偶数时 F[N] = 4 * F[N-2] - F[N-4]
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
const int mod = 100003;
int f[maxn];
int main(){
f[2] = 3;
f[4] = 11;
int n;
for(int i = 6;i < maxn;i+=2)f[i] = ((4*f[i-2])%mod -f[i-4]+mod)%mod;
while(~scanf("%d",&n)&&n){
if(n&1){puts("0");continue;}
printf("%d\n",f[n]);
}
return 0;
}
I题
//dp[i][j] = dp[i-1][j-1] + dp[i-1]][j]
#include<bits/stdc++.h>
using namespace std;
const int maxn = 40;
int a[maxn][maxn];
void dp(){
for(int i=1;i<35;i++)
a[i][0]=a[i][i]=1;
for(int i=1;i<35;i++)
for(int j=1;j<i;j++)
a[i][j]=a[i-1][j]+a[i-1][j-1];
}
int main(){
int k,n,m,i,j,s;
scanf("%d",&k);
dp();
while(k--){
scanf("%d%d",&n,&m);
if((n-m)%2!=0) printf("0\n");
else{
s=(n-m)/2;
dp();
printf("%d\n",a[n][s]);
}
}
}