原题链接:http://codevs.cn/problem/1163/
题目中的数据按照深搜的顺序给出,非常有意思。
可以将艺术馆看做一棵树,展室为叶子节点,1号为根节点,f[i][j]表示在以i为根节点的子树中停留s秒能够拿到的画的数量。
因为并不是所有的点都能及时逃出,所以要预留出(t*2)的时间来确保能够走回父亲节点。
如果这个点不是叶子节点,便必须继续向下搜索,左右两棵子树都递归完毕后,统计最大值。
如果这个点是叶子节点,那么在保证回到父亲节点的情况下,就可以拿画了,最多拿b幅。
#include<cstdio> #include<algorithm> using namespace std; int s,sum; int f[1005][1005]; void dfs(int x) { int t,b; scanf("%d %d",&t,&b); sum++; if(b==0) { dfs(x+1); int r=sum; dfs(r+1); for(int i=(t<<1);i<=s;i++) { for(int j=0;j<=i-(t<<1);j++) f[x][i]=max(f[x][i],f[x+1][j]+f[r+1][i-j-(t<<1)]); } } else { for(int i=(t<<1);i<=min(b*5+(t<<1),s);i++) f[x][i]=(i-(t<<1))/5; } } int main() { scanf("%d",&s); dfs(1); printf("%d",f[1][s]); return 0; }
18.3.15
在luogu上再次发现这道题,但是,两个OJ数据的制只有作人似乎理解不同,在洛谷上,因为“在警察到来之前”,所以在艺术馆内停留的时间实际只有s-1秒。