CDOJ 每周一题Div2 吃饭不积极,思想有问题(贪心+dp)

这里写图片描述

题目大意:……

思路及解析:刚拿到这道题目,恩,感觉就是个豆比贪心题,淦!
Submit! —->Wa1
和往常一样,蒟蒻又惊了,这难道不是按吃饭时间排个序然后每次新来的人到排队时间最短的队伍中去吗???

转念一想,噫…看来还是要dp
那么这个dp该怎么开呢,如果想把每一个状态暴力的表示出来最多需要2^200,但实际上我们只要考虑一个窗口有哪些人去排队吃饭就行了,这样的话dp[2][200*200+5]就可以暴力出来了

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<vector>
#include<set>
#include<queue>
#include<limits.h>
#include<string.h>
#include<map>
#include<list>
using namespace std;
typedef long long ll;

#define inf int(0x3f3f3f3f)
#define mod int(1e9+7)
#define eps double(1e-6)
#define pi acos(-1.0)
#define lson  root << 1
#define rson  root << 1 | 1

/*************

Hack announcement
*****
Unfortunately, your solution on A has been hacked :(

*************/


int n;

struct edge
{
    ll wait;
    ll dur;
} a[100005];

int shu1[100005];

int shu2[100005];

ll dp[2][205*205];

bool cmp(edge x,edge y)
{
    if(x.dur!=y.dur)
        return x.dur>y.dur;
    return x.wait<y.wait;
}

ll sum[200*200*5];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    memset(sum,0,sizeof(sum));
    for(int i=1; i<=n; i++)
        cin>>a[i].wait>>a[i].dur;
    sort(a+1,a+n+1,cmp);
    int now=0;
    int per=1;
    memset(dp[now], inf, sizeof(dp[now]));
    dp[0][0] = 0;
    for(int i = 1; i <= n; ++i)
    {
        sum[i] = sum[i - 1] + a[i].wait;
        swap(now, per);
        memset(dp[now], inf, sizeof(dp[now]));
        for(int j = 0; j <200*200+5; ++j)
        {
            dp[now][j] = max(dp[per][j], sum[i] - j + a[i].dur);
            if(j >= a[i].wait)
                dp[now][j] = min(dp[now][j], max(dp[per][j - a[i].wait], j + a[i].dur));
        }
    }
    ll da=inf;
    //cout<<now<<endl;
    for(int i=1;i<=200*200+5;i++)
        da=min(da,dp[now][i]);
    cout<<da<<endl;
}

猜你喜欢

转载自blog.csdn.net/murphyc/article/details/79505795