偷天换日 树形DP+背包

A. 偷天换日

内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较  

题目描述

神偷对艺术馆内的名画垂涎欲滴准备大捞一把。艺术馆由若干个展览厅和若干条走廊组成。每一条走廊的尽头不是通向一个展览厅,就是分为两个走廊。每个展览厅内都

有若干幅画,每幅画都有一个价值。经过走廊和偷画都是要耗费时间的。警察会在第n秒到达进口,在不被逮捕的情况下你最多能得到的价值

输入格式

第一行一个整数 n

第二行若干组整数,对于每组整数(t,x),t表示进入这个展览厅或经过走廊要耗费t秒的时间,若x>0表示走廊通向的展览厅内有x幅画,接下来x对整数(w,c)表示偷一幅价值为w的画需要c秒的时间。若x=0表示走廊一分为二。

输入是按深度优先给出的。

输出格式

仅一个整数,表示能获得的最大价值。

样例

样例输入

50
5 0 10 1 10 1 5 0 10 2 500 1 1000 2 18 1 1000000 4

样例输出

1500

数据范围与提示

n≤600;t,c≤5;x≤30

房间和走廊数不超过300个。

注意题目要求你在不被逮捕的情况下得到最多的价值

样例的输入对应于偷天换日 树形DP+背包


思路:递归建边,同时进行背包DP+决策
注意,fm数组表达的含义,因为要加上走廊的时间!! #include<bits/stdc++.h> #define re register int #define ll long long using namespace std; ll t,n,st,ust; ll w,c;      ll fm[1100][1100]; void in(int st) {     ll a,b;     scanf("%lld%lld",&a,&b);     if(b==0)     {         in(st<<1);         in(st<<1|1);         for(re i=n-a*2;i>=0;i--)         {             for(re j=i;j>=0;j--)             {                 fm[st][i+a*2]=max(fm[st][i+a*2],fm[st<<1][j]+fm[st<<1|1][i-j]);/*cout<<fm[st<<1][j+2*a]+fm[st<<1|1][i-j]<<endl;*/             }         }     }     else     {         for(re i=1;i<=b;i++)         {             scanf("%lld%lld",&w,&c);             for(re j=n;j>=c+a*2;j--)                 fm[st][j]=max(fm[st][j],fm[st][j-c]+w)/*,cout<<fm[st][j]<<endl*/;         }     }     //cout<<"a="<<a<<" b="<<b<<endl; //  return; } int main() {     scanf("%lld",&n);     n--;     in(1);     /*for(int i=1;i<=n;i++)         cout<<fm[1][i]<<endl;*/     printf("%lld",fm[1][n]);     return 0; }

 

上一篇:高级Redis应用进阶课 一站式Redis解决方案


下一篇:clementine for Mac(多平台音乐管理播放软件)