挑战程序设计竞赛 算法和数据结构 第11章 动态规划法
11.2 菲波那切数列
ALDS1_10_A:Fibonacci Number
原书AC代码:
//ALDS1_10_A:Fibonacci Number
//C
#include <stdio.h>
int dp[50];
int fib(int n){
if(n==0||n==1)return dp[n]=1;
if(dp[n]!=-1)return dp[n];
return dp[n]=fib(n-1)+fib(n-2);
}
int main(){
int n,i;
for(i=0;i<50;i++)dp[i]=-1;
scanf("%d",&n);
printf("%d\n",fib(n));
return 0;
}
//ALDS1_10_A:Fibonacci Number
//C++
#include <iostream>
using namespace std;
int main(){
int n;cin>>n;
int F[50];
F[0]=F[1]=1;
for(int i=2;i<=n;i++)F[i]=F[i-1]+F[i-2];
cout<<F[n]<<endl;
return 0;
}
仿照上述代码,本人编写的C语言AC代码如下:
//ALDS1_10_A:Fibonacci Number
//提交,Presentation Error,加上\n,提交AC 2017-11-5 16:04
#include <stdio.h>
int main(){
int n,a,b,c,i;
scanf("%d",&n);
a=1,b=1,c=1;
for(i=2;i<=n;i++){
c=a+b;
a=b,b=c;
}
printf("%d\n",c);//此处写成 printf("%d",c); Presentation Error
return 0;
}
11.3 最长公共子序列
ALDS1_10_C:Longest Common Subsequence
原书代码无法AC,略作改动代码如下,已AC:
//ALDS1_10_C:Longest Common Subsequence
//C++
//原书代码,一直无输出,一直以为是string问题,突然间发现 int c[N+1][N+1];是大数组,不能放在函数体内申明
//必须放在函数体外申明
//故原书代码无法AC,需要修改, int c[N+1][N+1];//注意,大数组要移到函数体外申明。 2017-11-3 21:17
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
static const int N = 1000;
int c[N+1][N+1];//注意,大数组要移到函数体外申明。
int lcs(string X,string Y){
int m=X.size();
int n=Y.size();
int max1=0;
X=' '+X;//在X[0]中插入空格
Y=' '+Y;//在Y[0]中插入空格
for(int i=1;i<=m;i++)c[i][0]=0;
for(int j=1;j<=n;j++)c[0][j]=0;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(X[i]==Y[j]){
c[i][j]=c[i-1][j-1]+1;
}else{
c[i][j]=max(c[i-1][j],c[i][j-1]);
}
max1=max(max1,c[i][j]);
}
}
return max1;
}
int main(){
string s1,s2;
int n;cin>>n;
for(int i=0;i<n;i++){
cin>>s1>>s2;
cout<<lcs(s1,s2)<<endl;
}
return 0;
}
仿照上述代码,本人编写的C语言AC代码如下:
//ALDS1_10_C:Longest Common Subsequence
//样例通过,提交Wrong Answer
//仔细想了想数据生成的过程,必须把字符串第0位空出,否则会出现数组元素下标为负数
//修改,提交,AC 2017-11-3 20:47
#include <stdio.h>
#include <string.h>
char a[1100],b[1100];
int c[1100][1100];
int max(int a,int b){
return a>b?a:b;
}
void lcs(char a[],char b[]){
int alen,blen,i,j;
alen=strlen(a),blen=strlen(b);
for(i=0;i<alen;i++)c[i][0]=0;
for(j=0;j<blen;j++)c[0][j]=0;
for(i=1;i<alen;i++)
for(j=1;j<blen;j++)
if(a[i]==b[j])c[i][j]=c[i-1][j-1]+1;
else c[i][j]=max(c[i-1][j],c[i][j-1]);
}
int main(){
int t,alen,blen,i;
scanf("%d",&t);
while(t--){
scanf("%s%s",a+1,b+1);//此时a[0]='\0' b[0]='\0'
a[0]=' ',b[0]=' ';//让a[0]一直到a[]都有数据 这次弄明白了a+1,b+1的移位读取了
lcs(a,b);
printf("%d\n",c[strlen(a)-1][strlen(b)-1]);
}
return 0;
}
11.4 矩阵链乘法
ALDS1_10_B:Matrix Chain Multiplication
原书AC代码:
//ALDS1_10_B:Matrix Chain Multiplication
//C++ 2017-11-5 15:46
#include <iostream>
#include <algorithm>
using namespace std;
static const int N=100;
int main(){
int n,p[N+1],m[N+1][N+1];
cin>>n;
for(int i=1;i<=n;i++){
cin>>p[i-1]>>p[i];
}
for(int i=1;i<=n;i++)m[i][i]=0;
for(int L=2;L<=n;L++){//因l(字母)1(数字)分不清,本人将其改为大写字母L
for(int i=1;i<=n-L+1;i++){
int j=i+L-1;
m[i][j]=(1<<21);//本人注解,相当于INF
for(int k=i;k<=j-1;k++){
m[i][j]=min(m[i][j],m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]);
}
}
}
cout<<m[1][n]<<endl;//本人注解,注意此处是1(数字)而不是l(字母)
return 0;
}
仿照上述代码,本人编写的C语言AC代码如下: