#include<bits/stdc++.h>
using namespace std;constint N =40;int n, m, dp[N][N];intmain(){
cin >> n >> m;//第0次传球在0号同学手中的方法数是1,即初始状态
dp[0][0]=1;//状态转移依赖于上一次传球的状态,所以外循环是1...mfor(int i =1; i <= m; i ++){for(int j =0; j < n; j ++){//dp[i][j]表示第i次传球在j号同学手中的方法数
dp[i][j]= dp[i-1][(j+1)%n]+ dp[i-1][(j-1+n)%n];}}
cout << dp[m][0]<< endl;return0;}
2007 普及组T3 守望者的逃离
时间复杂度:O(T*M),超时
#include<bits/stdc++.h>
using namespace std;constint M =1e3+100;int m, s, t, maxx;int a[M], b[M];intmain(){
cin >> m >> s >> t;//b[j]表示上一秒剩余j点魔法值,能走的最远距离//a[j]表示现在剩余j点魔法值,能走的最远距离for(int i =1; i <= t; i ++){
maxx =0;for(int j =0; j <= m; j ++){
a[j]= b[j]+17;//不使用魔法if(j +10<= m) a[j]=max(a[j], b[j+10]+60);//使用魔法if(j >=4) a[j]=max(a[j], b[j-4]);//原地休息
maxx =max(maxx, a[j]);}memcpy(b, a,sizeof(a));//a数组复制到b数组if(maxx >= s){
cout <<"Yes"<< endl << i << endl;return0;}}
cout <<"No"<< endl << maxx << endl;return0;}
时间复杂度:O(T)
#include<bits/stdc++.h>
using namespace std;constint M =3e5+10;int m, s, t, maxx;int a[M], b[M];intmain(){
cin >> m >> s >> t;//a和b两个人选择不同的策略,a[i]和b[i]分别表示他们在第i秒钟走的距离for(int i =1; i <= t; i ++){//a:优先使用魔法,如果魔法值不够,就休息恢复if(m >=10) a[i]= a[i-1]+60, m -=10;else a[i]= a[i-1], m +=4;//b:优先跑步,但如果a更快的话,就抄作业;
b[i]= b[i-1]+17;if(a[i]> b[i]) b[i]= a[i];//显然,b跑的不会比a慢if(b[i]>= s){
cout <<"Yes"<< endl << i << endl;return0;}}
cout <<"No"<< endl << b[t]<< endl;return0;}
2003普及组T2 数字游戏
#include<bits/stdc++.h>
using namespace std;constint N =105, M =10, INF =0x3f3f3f3f;int n, m;int a[N], s[N];int mi[N][N][M], ma[N][N][M], minn, maxx;intmain(){
cin >> n >> m;for(int i =1; i <= n; i ++) cin >> a[i], a[i+n]= a[i];for(int i =1; i <=2*n; i ++) s[i]= s[i-1]+ a[i];
maxx =0, minn = INF;memset(mi,0x3f,sizeof(mi));for(int len =1; len <= n; len ++){//枚举长度,状态转移依赖于更短的lenfor(int l =1; l + len -1<=2*n; l ++){//枚举起点int r = l + len -1;//终点由起点和长度决定
mi[l][r][1]= ma[l][r][1]=((s[r]- s[l-1])%10+10)%10;for(int i =2; i <= m; i ++){//枚举分块数//j - l + 1 = i - 1for(int j = l + i -2; j < r; j ++){//把a[l...j]分成i-1块,a[j+1...r]为一块int t =((s[r]-s[j])%10+10)%10;
mi[l][r][i]=min(mi[l][r][i], mi[l][j][i-1]* t);
ma[l][r][i]=max(ma[l][r][i], ma[l][j][i-1]* t);}}}}for(int i =1; i <= n; i ++){
minn =min(minn, mi[i][i+n-1][m]);
maxx =max(maxx, ma[i][i+n-1][m]);}
cout << minn << endl;
cout << maxx << endl;return0;}
2020普及组T4 方格取数
#include<bits/stdc++.h>#defineLLlonglong
using namespace std;constint N =1e3+10;int n, m, a[N][N];
LL dp[N][N][2];//dp[i][j][0]表示从左边或上面走过来的路径的最大值//dp[i][j][1]表示从左边或下面走过来的路径的最大值
LL myMax(LL a, LL b, LL c){returnmax(a,max(b, c));}intmain(){
cin >> n >> m;for(int i =1; i <= n; i ++)for(int j =1; j <= m; j ++) cin >> a[i][j];memset(dp,0xcf,sizeof(dp));
dp[1][0][0]=0;for(int j =1; j <= m; j ++){for(int i =1; i <= n; i ++){
dp[i][j][0]=myMax(dp[i-1][j][0], dp[i][j-1][0], dp[i][j-1][1])+ a[i][j];}for(int i = n; i >=1; i --){
dp[i][j][1]=myMax(dp[i+1][j][1], dp[i][j-1][0], dp[i][j-1][1])+ a[i][j];}}
cout << dp[n][m][0]<< endl;return0;}