求该记搜复杂度
查看原帖
求该记搜复杂度
540177
wyf_sinon楼主2024/8/22 13:40

玄关

#include<bits/stdc++.h>
using namespace std; 
#define int long long
const int N = 30 ;
int n ; 
int C[N];
int f[N][N][N];//f[x][l][r] x为根 区间[l,r]
int rt[N][N];//rt[l][r]为[l,r]最优解的根
vector<int> P;
int ans;
int dp(int x,int l,int r)
{
	if(f[x][l][r]) return f[x][l][r];
	if(l==r) return f[x][l][r]=C[l];
	if(l>r) return 1;
	int res = 0 ;
	if(l==x)//边界
	{
		for(int j=x+1;j<=r;j++)
		{
			if(dp(j,x+1,r)>res)
			{
				res = dp(j,x+1,r) ;
				rt[x+1][r] = j ;
			} 
		} 
	}
	for(int i=l;i<x;i++)
	{
		for(int j=x+1;j<=r;j++)
		{
			if( dp(i,l,x-1) * dp(j,x+1,r) > res )
			{
				res = dp(i,l,x-1) * dp(j,x+1,r) ;
				rt[l][x-1] = i ;
				rt[x+1][r] = j ;
			} 
		}
		if(x==r) //边界
		{
			if( dp(i,l,x-1) > res )
			{ 
				res = dp(i,l,x-1) ;
				rt[l][x-1] = i ;
			} 
		}
	}
	return f[x][l][r] = res + C[x] ;
}
void GetPath(int l,int r)
{ 
	if(l==r) 
	{
		P.push_back(l);
		return ;
	}
	int x = rt[l][r] ;
	P.push_back(x);
	if(x>l) GetPath(l,x-1);
	if(x<r) GetPath(x+1,r);
	return ;
}
signed main()
{    
	scanf("%lld",&n);
	for(int i=1;i<=n;i++) scanf("%lld",C+i);
	for(int i=1;i<=n;i++)
	{
		if(dp(i,1,n)>ans)
		{
			rt[1][n]=i;
			ans= dp(i,1,n) ; 
			P.clear();
			GetPath(1,n);
		} 
	} 
	printf("%lld\n",ans);
	for(auto x:P) printf("%lld ",x);
}

我认为状态数为n^3 而记搜保证了只会看一遍
所以是n^3吗(
还是转移乘上状态数最后是n^5捏

2024/8/22 13:40
加载中...