實驗四

最長公共子序列

#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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章