【洛谷luogu】P1270-“访问”美术馆(树形DP)

原题链接:https://www.luogu.org/problemnew/show/P1270

题目大意

同 P3360 ,只不过是每幅画的时间固定为5秒,价值退化为个数。

解法

在P3360的代码上把时间改为5秒,把价值改为1即可……

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define for1(i, n) for (int i = 1; i <= (int)(n); ++i)
#define pb push_back

using namespace std;
typedef long long LL;
const int N=1000+5;
struct Node{
	int lchild,rchild,w,x;
}Tree[N];
int cnt=0;
int New(int w,int x){
	Tree[++cnt].w=w;
	Tree[cnt].x=x;
	Tree[cnt].lchild=-1;
	Tree[cnt].rchild=-1;
	return cnt;
}
int dp[300+5][30+5][600+5];
int Build(){
	int t,x,w,c;
	cin>>t>>x;
	int r=New(t,x);
	if(x>0){
		//dp[300][30][600]
	//	cout<<"r is "<
		for(int i=1;i<=x;i++){
		//	cin>>w>>c;
			w=1;c=5;
			for(int j=1;j<=600;j++){
				if(j>=c) dp[r][i][j]=max(dp[r][i-1][j],dp[r][i-1][j-c]+w);
else dp[r][i][j]=dp[r][i-1][j];
			//	cout<
			}
	//		cout<
		}
	//	cout<
	}
	else if(x==0){
		Tree[r].lchild=Build();
		Tree[r].rchild=Build();
	}
	return r;
}

void dfs(int u){
	if(Tree[u].x>0) return ;
	int l=Tree[u].lchild;
	int r=Tree[u].rchild;
	dfs(l);
	dfs(r);
	int lx=(Tree[l].x>0?Tree[l].x:2);
	int rx=(Tree[r].x>0?Tree[r].x:2);
	int lw=Tree[l].w;
	int rw=Tree[r].w;
	for(int i=0;i<=600;i++){
		for(int j=0;j+i<=600;j++){
			dp[u][2][i+j]=max(dp[u][2][i+j],(i-2*lw>=0?dp[l][lx][i-2*lw]:0)+(j-2*rw>=0?dp[r][rx][j-2*rw]:0));
		}
	}
}


int main() {

#ifdef LOCAL_DEFINE
	freopen("input.in", "rt", stdin);
#endif
	int n;
	cin>>n;
	int r=Build();
	dfs(r);
	int rw=Tree[r].w;
	cout<<dp[r][2][n-2*rw-1]<<endl;

#ifdef LOCAL_DEFINE
	cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
#endif
	return 0;
}


你可能感兴趣的:(算法与数据结构,算法,luogu)