码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-02-16 15:23:53      阅读:246      评论:0      收藏:0      [点我收藏+]

标签:免费   return   关联   size   顺序   i++   c++   name   i+1   

技术图片

题目描述

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\n",ans+1);
    return 0;
}

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

标签:免费   return   关联   size   顺序   i++   c++   name   i+1   

原文地址:https://www.cnblogs.com/chhokmah/p/10387730.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!