传送门:“访问”美术馆 - 洛谷
思路:与二叉苹果树类似
一般来说都想着先建好图,再去做,但这道题可以边输入边做。个别需要注意的点,美术馆的走廊需要走两遍,所以要自乘2,警察到达时间不能刚好用完,所以要自减1.
整一个图可以变成一个二叉树,树上的节点就是一条走廊,物品都依附在这个走廊节点上面。
状态表示:f[i][j]表示在以点i为根形成的树中花费j秒所能取得的最大价值。
状态计算:f[root][j]=min((j-time)/5,n); (j-time)/5表示j秒内所能偷的画作数量,与当前最大的数量n取一个最小值就是所能取走的最大数量。
无建图代码:
#include<iostream>
#include<cstring>
#include <cmath>
#include<algorithm>
#include <vector>
using namespace std;
const int N=1e3+10;
int n,m,ans,u;
int f[N][N];
void dfs()
{
int root=++u;
int time,n;
cin>>time>>n;
time*=2;
if(n)
{
for(int j=time;j<=m;j++)
f[root][j]=min((j-time)/5,n);
}else
{
int l=u+1;dfs();
int r=u+1;dfs(); //在该方案组中
for(int j=time;j<=m;j++) //先枚举背包容量
for(int k=0;k<=j-time;k++) //再枚举决策
f[root][j]=max(f[root][j],f[l][k]+f[r][j-time-k]);
}
}
int main()
{
cin>>m;
m--;
dfs();
cout<<f[1][m];
return 0;
}