递推题目大整理

我是被逼的,做这种鸟递推

 

//HDU 2524 //行列相乘,先处理行的情况,接着把一行看成一个元素 #include<cstdio> int main() { int n,m,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); int sum=(n*(n+1))>>1; int k=(m*(m+1))>>1; printf("%d/n",sum*k); } return 0; }  

 

 

//两个叉,每个交点产生一个区域,并且每个叉的交集又一个 //HDU 2050 #include<cstdio> int f[10001]; int main() { f[1]=2; for(int i=2;i<=10000;i++) f[i]=f[i-1]+4*i-3; int n,t; scanf("%d",&t); while(t--) { scanf("%d",&n); printf("%d/n",f[n]); } return 0; } 

 

 


 

//根据倒数第一个和第一个颜色相同,不相同的进行讨论 //HDU 2045 #include<cstdio> int f[60]; int main() { int n; f[1]=3; f[2]=6; f[3]=6; for(int i=4;i<=50;i++) f[i]=f[i-1]+f[i-2]*2; while(scanf("%d",&n)!=EOF) { printf("%d/n",f[n]); } return 0; }

 

 

//hdu 2502 /*很快就推出来了, f[1]=1 f[2]=2 f[3]=4 f[4]=8...... 表示每个N二进制有的个数(1开头的) 接着g[n]=(g[n-1]+f[n-1])+.....+1 每个g[n-1]最前面加上1,即得 */ #include<cstdio> int f[21],g[21]; int main() { f[1]=1; g[1]=1; for(int i=2;i<=20;i++) f[i]=f[i-1]*2; for(int i=2;i<=20;i++) { g[i]=0; for(int j=1;j<i;j++) g[i]+=g[j]+f[j]; g[i]+=1; } int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); printf("%d/n",g[n]); } return 0; }

 

 

/************************************************************************ hdu 2604 一个合法串可以由两个较短的合法串组成 就以d[n]为例:(注意不能重复) 1、n-1个字符的时候: +m (+f已经在下面的情况中被考虑了,这里不能乱加f,会矛盾) 2、n-2: 只能+mm,会和n-1重复,所以不考虑n-2 3、n-3: +mmf (不能乱加mff) 4、n-4: +mmff 5、n-5: 如果是+mmffm,会与n-1重复,+mmmff会与n-4重复,+mmmmf会与n-3重复(不考虑) 所以就考虑n-1,n-3,n-4,DP等式就出来了:dp[n]=dp[n-1]+dp[n-3]+dp[n-4] n<10^6 m<=30 矩阵乘法加速 ************************************************************************/ #include<cstdio> #include<cstring> int MOD,L; int ANS[4][4]; int A[4][4]= { 1,1,0,0, 0,0,1,0, 1,0,0,1, 1,0,0,0 }; void mul(int A[][4],int B[][4]) { int R[4][4]; memset(R,0,sizeof(R)); for(int k=0; k<4; k++) for(int i=0; i<4; i++) if(A[i][k]) for(int j=0; j<4; j++) R[i][j]=(R[i][j]+A[i][k]*B[k][j])%MOD; for(int i=0; i<4; i++) for(int j=0; j<4; j++) A[i][j]=R[i][j]; } void power(int m[][4],int n) { if(n==1) { for(int i=0; i<4; i++) for(int j=0; j<4; j++) m[i][j]=A[i][j]; return; } power(m,n/2); mul(m,m); if(n&1)mul(m,A); } int main() { while(~scanf("%d%d",&L,&MOD)) { int num[5] = {0,2,4,6,9}; if(L<=4)printf("%d/n",num[L]%MOD); else { power(ANS,L-4); int ans = 0; for(int i=0; i<4; i++) ans+=num[4-i]*ANS[i][0]; printf("%d/n",ans%MOD); } } return 0; }

 

 

 

/* 当n==1||m==1时,只有一种分法; 当n<m时,record[n][m]=record[n][n]; 当n==m时,那么就得分析是否要分出m这一个数,如果要分那就只有一种{m},要是不分,那就是把n分成不大于m-1的若干份;即record[n][n]=1+record[n][n-1]; 当n>m时,那么就得分析是否要分出m这一个数,如果要分那就{{m},{x1,x2,x3..}}时n-m的分法record[n-m][m],要是不分,那就是把n分成不大于m-1的若干份; 即record[n][n]=record[n-m][m]+record[n][m-1]; */ #include<cstdio> int record[125][125]; int main() { for(int i=1; i<=121; i++) record[1][i]=record[i][1]=1; for(int i=2; i<121; i++) for(int j=2; j<=121; j++) { if(i<j) record[i][j]=record[i][i]; if(i==j) record[i][j]=1+record[i][j-1]; if(i>j) record[i][j]=record[i-j][j]+record[i][j-1]; } int n; while(scanf("%d",&n)!=EOF) { printf("%d/n",record[n][n]); } return 0; }

 

 

你可能感兴趣的:(递推题目大整理)