hgoi#2019/2/16--t3--psolve

Posted chhokmah

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hgoi#2019/2/16--t3--psolve相关的知识,希望对你有一定的参考价值。

技术图片

题目描述

Dustar有n道题目要做。他的月薪是m元。

由于题目是一流的难题,所以Dustar不得不找个人来帮(代)助(替)他写作业。

找人写作业不是免费的,但是他们能保证在一个月内做出任何题目。每做一道题需要两笔付款,第一笔ai元在做题的那一个月初支付,第二笔b[i]元(1<=b[i]<=m)在做完后的下一个月初支付。每一个月Dustar用上一个月挣的钱来付款。

Dustar没有任何存款意识,所以每个月的节余都回拿用去买糖吃掉了。

因为题目是相互关联的,它们必须按顺序解出。比如,题目3必须在题目4之前或同一个月解出。

请问做完所有题目并支付完所有款项的最少月数。

解法

第一眼看到这道题会想到贪心,如果当前可以放到下一个月里去,但是这样很明显是错的。。。

试试这组数据

10 9
1 9
9 1

这样就会被卡住,那么怎么做?

那么就是DP。我们设置(f[i][j])表示到第(i)天买了(j)物品的答案。

我们每次看一下前后天是否满足状态就好了。

ac代码

#include<bits/stdc++.h>
#define N 305
using namespace std;
int f[N][N],a[N],b[N];
int n,m;
int r(){
    int w=0,x=0;char ch=0;
    while(!isdigit(ch))w|=ch=='-',ch=getchar();
    while(isdigit(ch))x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    return w?-x:x;
}
int main(){
    m=r(),n=r();
    for(int i=1;i<=n;i++)a[i]=r(),b[i]=r();
    memset(f,-1,sizeof(f));
    f[1][0]=m;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=n;j++) {
            if(f[i][j]<0) break;
            int res1=f[i][j],res2=m;
            f[i+1][j]=max(f[i+1][j],m);
            for(int k=j+1;k<=n;k++){
                if(res1-a[k]<0||res2-b[k]<0) break;
                res1-=a[k],res2-=b[k];
                f[i+1][k]=max(f[i+1][k],res2);
            }
        }
    }
    int ans;
    for(int i=1;i<=2*n;i++){
        if(f[i][n]!=-1){ans=i;break;}
    }
    printf("%d
",ans+1);
    return 0;
}

以上是关于hgoi#2019/2/16--t3--psolve的主要内容,如果未能解决你的问题,请参考以下文章

hgoi#20191115

HGOI 20190828 题解

hgoi#20190514

HGOI 20190310 题解

HGOI 20191106 题解

HGOI 20190303 题解