两种区间dp,40pt和80pt,求调
查看原帖
两种区间dp,40pt和80pt,求调
431995
arfdou楼主2024/9/29 17:10

环状

#include <bits/stdc++.h>
using namespace std;
#define li long long 
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
li vertices[101];
bool edge[101];
li f[101][101];
li m[101][101]; 
const li limin=-9223372036854775807;
const li limax=9223372036854775807;
li tmax=limin;
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		char m;
		cin>>m;
		edge[i]= m=='x'?1:0;//1是乘,0是+ 
		cin>>vertices[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			f[i][j]=limin;
			m[i][j]=limax;
		}
	}
	for(int i=1;i<=n;i++){
		f[i][i]=vertices[i];
		m[i][i]=vertices[i];
	}
	for(int len=2;len<=n;len++){
		for(int i=1;i<=n;i++){
			int r=(i+len-2)%n+1;
			for(int k=i;k<=i+len-2;k++){
				if(edge[k%n+1]){
					li p=max(max(f[i][(k-1)%n+1]*f[k%n+1][r],m[i][(k-1)%n+1]*m[k%n+1][r]),max(f[i][(k-1)%n+1]*m[k%n+1][r],f[i][(k-1)%n+1]*m[k%n+1][r]));
					f[i][r]=max(f[i][r],p);
					li q=min(min(m[i][(k-1)%n+1]*m[k%n+1][r],f[i][(k-1)%n+1]*f[k%n+1][r]),min(f[i][(k-1)%n+1]*m[k%n+1][r],f[i][(k-1)%n+1]*m[k%n+1][r]));
					m[i][r]=min(m[i][r],q);

				}else{
					f[i][r]=max(f[i][r],f[i][(k-1)%n+1]+f[k%n+1][r]);
					m[i][r]=min(m[i][r],m[i][(k-1)%n+1]+m[k%n+1][r]);
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(f[i][(i-2)%n+1]>tmax){
			tmax=f[i][(i-2)%n+1];
		}
	}
	cout<<tmax<<endl;
	for(int i=1;i<=n;i++){
		if(f[i][(i-2)%n+1]==tmax){
			cout<<i<<' ';
		}
	}
	
	return 0;
}

断链的区间dp

#include <bits/stdc++.h>
using namespace std;
#define li long long 
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
li vertices[101];
bool edge[101];
li f[101][101];
li m[101][101]; 
const li limin=-9223372036854775807;
const li limax=9223372036854775807;
li tmax=limin;
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		char m;
		cin>>m;
		edge[i]= m=='x'?1:0;//1是乘,0是+ 
		cin>>vertices[i];
	}
	for(int i=1;i<=n;i++){
		vertices[i+n]=vertices[i];
		edge[i+n]=edge[i];
	} 
	for(int i=1;i<=2*n;i++){
		for(int j=1;j<=2*n;j++){
			f[i][j]=limin;
			m[i][j]=limax;
		}
	}
	for(int i=1;i<=n;i++){
		f[i][i]=vertices[i];
		m[i][i]=vertices[i];
	}
	for(int len=2;len<=n;len++){
		for(int i=1;i<=2*n-1&&i+len-1<=2*n;i++){
			int r=i+len-1;
			for(int k=i;k<=i+len-2;k++){
				if(edge[k+1]){
					li p=max(max(f[i][k]*f[k+1][r],m[i][k]*m[k+1][r]),max(f[i][k]*m[k+1][r],f[i][k]*m[k+1][r]));
					f[i][r]=max(f[i][r],p);
					li q=min(min(m[i][k]*m[k+1][r],f[i][k]*f[k+1][r]),min(f[i][k]*m[k+1][r],f[i][k]*m[k+1][r]));
					m[i][r]=min(m[i][r],q);
				}else{
					f[i][r]=max(f[i][r],f[i][k]+f[k+1][r]);
					m[i][r]=min(m[i][r],m[i][k]+m[k+1][r]);
				}
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(f[i][i+n-1]>tmax){
			tmax=f[i][i+n-1];
		}
	}
	cout<<tmax<<endl;
	for(int i=1;i<=n;i++){
		if(f[i][i-1]==tmax){
			cout<<i<<' ';
		}
	}
	
	return 0;
}
2024/9/29 17:10
加载中...