C小加

厚德 博学 求真 至善 The bright moon and breeze
posts - 145, comments - 195, trackbacks - 0, articles - 0
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

poj 1036 Gangsters (DP)

Posted on 2012-03-29 11:37 C小加 阅读(1650) 评论(1)  编辑 收藏 引用 所属分类: 解题报告

题意:宾馆有个可以伸缩的门,每秒钟可以伸长1个单位,或者缩小1个单位,或者原地不动。有N个强盗,每个强盗会在t的时间内到达并按,如果此时门的开方度和他的身材s正好相等,这个强盗就会进来,然后你就能得到p的加分。

初始状态门是关闭的,让你求出在t时刻得到的最大得分。

 

分析:按时间从小到大排序,t时间内最大的得分由t之前的时刻决定,满足无后效性,每一个时刻都能得到最优解,满足最有子结构,所以DP

F[i]表示第i个人。

当身材之差小于时间之差时F[i]=max(f[i],f[j]+ple[i].p) 0<=j<i 但得满足一个条件,第j个人已经进去,否则门伸长的宽度可能会小于身材。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAXM=103;

typedef struct People
{
    int t,p,s;

}People;
People ple[MAXM];
int f[MAXM];
bool cmp(People p1,People p2)
{
    return p1.t<p2.t;
}
int main()
{
    int n,k,s;
    scanf("%d %d %d",&n,&k,&s);
    for(int i=1;i<=n;++i)
        scanf("%d",&ple[i].t);
    for(int i=1;i<=n;++i)
        scanf("%d",&ple[i].p);
    for(int i=1;i<=n;++i)
        scanf("%d",&ple[i].s);
    sort(ple+1,ple+n+1,cmp);
    f[0]=0;
    ple[0].p=0;ple[0].s=0;ple[0].t=0;
    int ans=0;
    for(int i=1;i<=n;++i)
    {
        for(int j=i-1;j>=0;--j)
        {
            if(f[j]>=ple[j].p)//下一步做差的基础是第j个人已经进去。
                if(abs(ple[i].s-ple[j].s)<=ple[i].t-ple[j].t)
                    f[i]=max(f[i],f[j]+ple[i].p);
        }
        ans=max(ans,f[i]);
    }
    printf("%d\n",ans);

    return 0;
}

Feedback

# re: poj 1036 Gangsters (DP)  回复  更多评论   

2012-03-31 18:23 by alafeizai
。。。这个“前一个人需要能进去”坑了很多人啊。。。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理