实验四

xiaoxiao2025-12-05  6

最长公共子序列

#include<iostream> #include<string> #include<cmath> using namespace std; string a,b; int dp[210][210]; int main(){ cin>>a>>b; int sa=a.size(),sb=b.size(); for(int i=1;i<=sa;i++){ for(int j=1;j<=sb;j++){ if(a[i-1]==b[j-1])dp[i][j]=dp[i-1][j-1]+1; else{ dp[i][j]=max(dp[i][j-1],dp[i-1][j]); } } } cout<<dp[sa][sb]<<endl; return 0; }

防卫导弹

#include<iostream> #include<cstring> using namespace std; int n; int a[200],dp[200]; int cmax=1; int main(){ cin>>n; while(n!=0){ cmax=1; memset(dp,0,sizeof(dp)); for(int i=0;i<n;i++){ cin>>a[i]; dp[i]=1; } for(int i=1;i<n;i++){ for(int k=0;k<i;k++){ if(a[k]>=a[i]&&dp[k]+1>dp[i]){ dp[i]=dp[k]+1; } } if(dp[i]>cmax)cmax=dp[i]; } cout<<cmax<<endl; cin>>n; } return 0; }

矩阵连乘积

#include<iostream> #include<cstring> using namespace std; int n; int dp[15][15]; int a[15][2]; int main(){ cin>>n; memset(dp,0x3f,sizeof(dp)); for(int i=1;i<=n;i++){ cin>>a[i][0]>>a[i][1]; dp[i][i]=0; } for(int i=1;i<=n;i++){ for(int j=1;j+i-1<=n;j++){ for(int k=j;k<j+i-1;k++){ if(dp[j][k]+dp[k+1][j+i-1]+a[j][0]*a[k][1]*a[j+i-1][1]<dp[j][j+i-1]){ dp[j][j+i-1]=dp[j][k]+dp[k+1][j+i-1]+a[j][0]*a[k][1]*a[j+i-1][1]; } } } } cout<<dp[1][n]<<endl; return 0; }

田忌赛马

#include<iostream> #include<vector> #include<cstring> #include<algorithm> using namespace std; int n,ta,tb; vector<int> a,b; int dp[110][110]; bool cmp(int a,int b){ return a>b; } int main(){ cin>>n; while(n!=0){ memset(dp,0,sizeof(dp)); a.clear();b.clear(); for(int i=0;i<n;i++){ cin>>tb; b.push_back(tb); } for(int i=0;i<n;i++){ cin>>ta; a.push_back(ta); } sort(a.begin(),a.end(),cmp); sort(b.begin(),b.end(),cmp); for(int j=n-1;j>=0;j--){ for(int k=1;k<=n-j;k++){ if(a[j+k-1]<b[k-1]){ dp[j][k]=dp[j][k-1]+1; } else if(a[j+k-1]>b[k-1]){ dp[j][k]=dp[j+1][k-1]-1; } else if(a[j+k-1]==b[k-1]){ dp[j][k]=max(dp[j][k-1],dp[j+1][k-1]-1); } } } cout<<dp[0][n]<<endl; cin>>n; } return 0; }

石子合并

#include<iostream> #include<cstring> using namespace std; int n,a[210],b[110],sum[110],cmin=9999999; int dp[110][110]; int main(){ cin>>n; while(n){ cmin=9999999; memset(a,0,sizeof(a)); for(int i=0;i<n;i++){ cin>>a[i]; a[i+n]=a[i]; } for(int i=0;i<n;i++){//枚举起点 memset(dp,0x3f,sizeof(dp)); memset(b,0,sizeof(b)); memset(sum,0,sizeof(sum)); sum[0]=b[0]=a[i]; for(int j=1;j<n;j++){ b[j]=a[i+j]; sum[j]=sum[j-1]+b[j]; } for(int j=0;j<n;j++){ dp[j][j]=0; } for(int l=2;l<=n;l++){ for(int x=0;x+l-1<n;x++){ for(int k=x;k<x+l-1;k++){ if(dp[x][k]+dp[k+1][x+l-1]+sum[x+l-1]-sum[x-1]<dp[x][x+l-1]) dp[x][x+l-1]=dp[x][k]+dp[k+1][x+l-1]+sum[x+l-1]-sum[x-1]; } } } if(cmin>dp[0][n-1])cmin=dp[0][n-1]; } cout<<cmin<<endl; cin>>n; } return 0; }

旅游预算

#include<iostream> #include<iomanip> #include<vector> using namespace std; double Distance;//起点终点的距离 double tank;//车的油箱大小 double per_l_dis;//每升油可以走多远 double scost;//起点加油的价格 int n;//加油站的数目 struct station{ double dis;//距起点的距离 double cost;//每升油的价格 int next_station; }; station sts[55]; double dp[55];//从i号站点加满油到终点的最小花费 vector<int> v; int main(){ cin>>Distance>>tank>>per_l_dis>>scost; cin>>n; dp[0]=99999999; sts[0].dis=0; sts[n+1].dis=Distance; for(int i=1;i<=n;i++){ dp[i]=99999999; cin>>sts[i].dis>>sts[i].cost; //cout<<sts[i].dis<<' '<<sts[i].cost<<endl; } double longest=tank*per_l_dis;//加满油最远可以跑多少 for(int k=n;k>=0;k--){//枚举dp[k] if(sts[n+1].dis-sts[k].dis<=longest){ dp[k]=0;//直接可达到终点 sts[k].next_station=n+1; } else{ for(int i=k+1;i<=n;i++){//考察第k个加油站后面符合条件的加油站 if( ( sts[i].dis-sts[k].dis>=0.5*longest && sts[i].dis-sts[k].dis<=longest ) || ( sts[k].dis+longest<sts[i+1].dis && sts[k].dis+longest>=sts[i].dis ) ){ double ncost=(sts[i].dis-sts[k].dis)/per_l_dis*sts[i].cost; if(dp[i]+ncost<dp[k]){ dp[k]=dp[i]+ncost; sts[k].next_station=i; } } } } } int k=0; k=sts[k].next_station; while(k!=n+1){ v.push_back(k); k=sts[k].next_station; } cout<<fixed<<setprecision(2)<<dp[0]+scost+v.size()*2.0<<' '<<v.size()<<endl; for(int i=0;i<v.size();i++){ cout<<v[i]<<' '; } cout<<endl; return 0; }

滑雪

#include<iostream> using namespace std; int m[110][110]; int c,r; int dp[110][110]; int visited[110][110]; int dx[4]={0,1,0,-1}; int dy[4]={-1,0,1,0}; int cmax=0; int f(int i,int j){ if(visited[i][j])return dp[i][j]; int flag=0;//标志为0,则四周不存在可以滑到的地方 for(int k=0;k<4;k++){ int x=i+dx[k],y=j+dy[k]; if(x>=0&&x<c &&y>=0&&y<r &&m[i][j]>m[x][y] &&dp[i][j]<f(x,y)+1){ flag=1; dp[i][j]=dp[x][y]+1; visited[i][j]=1; } } if(flag==0){ visited[i][j]=1; return dp[i][j]=1; } else{ return dp[i][j]; } } int main(){ cin>>c>>r; for(int i=0;i<c;i++){ for(int j=0;j<r;j++){ cin>>m[i][j]; } } for(int i=0;i<c;i++){ for(int j=0;j<r;j++){ if(cmax<f(i,j))cmax=dp[i][j]; } } cout<<cmax<<endl; return 0; }

花生米(二)

#include<iostream> using namespace std; bool dp[1010]; int n; int main(){ cin>>n; dp[0]=dp[2]=dp[6]=dp[11]=dp[4]=dp[8]=dp[10]=1; dp[1]=dp[3]=dp[5]=dp[7]=dp[9]=0; for(int i=12;i<=1000;i++){ dp[i]=!(dp[i-1]&&dp[i-5]&&dp[i-10]); } while(n){ cout<<dp[n]<<endl; cin>>n; } return 0; }

花生米(三)

#include<iostream> using namespace std; bool dp[1010][510]; int visited[1010][510]; int n; bool f(int i,int j){ //cout<<i<<" "<<j<<endl; if(i<0||i==1)return 0; if(visited[i][j])return dp[i][j]; if(i==0||i-1<=j){ visited[i][j]=1; return dp[i][j]=1; } int flag=0; for(int k=1;k<=j;k++){ if(f(i-k,k*2)==0){ flag=1; break; } } if(flag){ visited[i][j]=1; return dp[i][j]=1; } else{ visited[i][j]=1; return dp[i][j]=0; } } int main(){ cin>>n; while(n){ cout<<f(n,1)<<endl; cin>>n; } return 0; }

花生米(四)

#include<iostream> using namespace std; int n; int a[15]; int main(){ cin>>n; while(n){ int sum=0; for(int i=0;i<n;i++){ cin>>a[i]; sum^=a[i]; } if(n%2==0){ if(sum)cout<<1<<endl; else cout<<0<<endl; } else{ if(sum)cout<<0<<endl; else cout<<1<<endl; } cin>>n; } return 0; }

花生米(五)

#include<iostream> #include<cstring> using namespace std; double n; int m; int dp[10010];//表示杰瑞先手,在剩余j的情况下能胜否,如果是0就应该汤姆先手 int main(){ cin>>n; m=int(n*10); while(m>0){ memset(dp,0,sizeof(dp)); for(int j=0;j<=m-10;j++){//枚举剩余多少 int i=m-j;//i表示已经吃了多少 if(i>j)dp[j]=0;//面对这种情况不会胜利,把它留给汤姆 else if(3*i>=j)dp[j]=1;//这一次就可以吃完,这种好事当然杰瑞不会放过 else{ int flag=0; for(int k=i;k<=3*i;k++){//枚举所有的可能吃法 if(dp[j-k]==0){ //只要在这些可能中,至少有一种可以使得汤姆先手败,那么杰瑞照着k个先取,就能到达那一种状态 flag=1; break; } } if(flag)dp[j]=1; else dp[j]=0; } } cout<<!dp[m-10]<<endl;//dp[m-10]的意思是先取10个以后,下一个人先取胜否,与题目问的正好相反,所以取反 cin>>n; m=int(n*10); } return 0; }

 

转载请注明原文地址: https://www.6miu.com/read-5040400.html

最新回复(0)