【bzoj1700】Problem Solving 解题

题目描述

过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场并且象普通人一样找到了工作. 他们的月薪是M (1 <= M <= 1000) 元. 他们的题目是一流的难题,所以他们得找帮手.帮手们不是免费的,但是他们能保证在一个月内作出任何题目.每做一道题需要两比付款, 第一笔A_i(1 <= A_i <= M) 元在做题的那一个月初支付, 第二笔B_i元(1 <= B_i <= M)在做完后的下一个月初支付. 每一个月牛们用上一个月挣的钱来付款. 牛没有任何存款意识, 所以每个月的节余都回拿用去买糖吃掉了. 因为题目是相互关连的,它们必须按大概顺序解出. 比如,题目3必须在解题目4 之前或同一个月解出. 找出牛们做完所有题目并支付完所有款项的最短月数.

输入

* 第一行: N 和 P

* 第2...P+1行: 第i行包含A_i和B_i, 分别是做第i道题的欲先付款和完成付款.

输出

* 第一行: 牛们做完题目和付完帐目的最少月数

样例输入

100 5

40 20

60 20

30 50

30 50

40 40

样例输出

6

提示


题解

动态规划。

第一眼看到这题以为是贪心。

然而贪心是错误的,有数据 50 5  40 10  10 40  10 5  10 3  10 2 作反例

于是想到动态规划。

设f[i][j]为一次性选[i,j]之内的题,且选完后该月不选其它题的最小月数。

那么可以推出f[j][i]=min(f[k][j-1]+2)

和f[j][i]=min(f[k][j-1]+1)(条件:选完[k , j-1]下个月剩余的钱足够选[j , i])

于是用前缀和求区间和,时间复杂度压缩为O(p^3),AC

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inf 0x3f3f3f3f
 5 using namespace std;
 6 int f[302][302] , a[302] , b[302] , suma[302] , sumb[302];
 7 int main()
 8 {
 9     int n , p , i , j , k , ans = inf;
10     scanf("%d%d" , &n , &p);
11     for(i = 2 ; i <= p + 1 ; i ++ )
12     {
13         scanf("%d%d" , &a[i] , &b[i]);
14         suma[i] = suma[i - 1] + a[i];
15         sumb[i] = sumb[i - 1] + b[i];
16     }
17     memset(f , 0x3f , sizeof(f));
18     f[1][1] = 1;
19     for(i = 2 ; i <= p + 1 ; i ++ )
20     {
21         for(j = 2 ; j <= i ; j ++ )
22         {
23             for(k = 1 ; k < j ; k ++ )
24             {
25                 if(f[k][j - 1] != inf && sumb[j - 1] - sumb[k - 1] <= n)
26                 {
27                     if(n >= suma[i] - suma[j - 1])
28                         f[j][i] = min(f[j][i] , f[k][j - 1] + 2);
29                     if(n - (sumb[j - 1] - sumb[k - 1]) >= suma[i] - suma[j - 1])
30                         f[j][i] = min(f[j][i] , f[k][j - 1] + 1);
31                 }
32             }
33         }
34     }
35     for(i = 2 ; i <= p + 1 ; i ++ )
36         if(sumb[p + 1] - sumb[i - 1] <= n)
37             ans = min(ans , f[i][p + 1] + 1);
38     printf("%d\n" , ans);
39     return 0;
40 }
时间: 2024-10-22 05:21:25

【bzoj1700】Problem Solving 解题的相关文章

【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划

[BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场并且象普通人一样找到了工作. 他们的月薪是M (1 <= M <= 1000) 元. 他们的题目是一流的难题,所以他们得找帮手.帮手们不是免费的,但是他们能保证在一个月内作出任何题目.每做一道题需要两比付款,

[bzoj1700]: [Usaco2007 Jan]Problem Solving 解题

不能贪心!不能贪心!不能贪心! 反正有反例(有的题目月初支付款很少,月末支付款很大,和前面的题凑到一个月的话可能导致下个月写不了= =这时放后一个月,和后面的题一起开始写可能更优) 比如: 50 440 15 1043 301 10 老老实实DP吧...f[i][j]表示在第i月过后,共解决了j道题,第i月结余(可用于下个月的月初支付)的最大值.cost0[].cost1[]分别表示月初支付和月末支付 f[i][j]=max{m-sum(cost1[k+1]....cost1[j])},(前提是

bzoj 1700: [Usaco2007 Jan]Problem Solving 解题 ——dp

Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地说,他们有P (1 <= P <= 300) 道题目要做. 他们还离开了农场并且象普通人一样找到了工作. 他们的月薪是M (1 <= M <= 1000) 元. 他们的题目是一流的难题,所以他们得找帮手.帮手们不是免费的,但是他们能保证在一个月内作出任何题目.每做一道题需要两比付款, 第一笔A_i(1 <= A_i <= M) 元在做题的那一个月初支付, 第二

bzoj 1700: [Usaco2007 Jan]Problem Solving 解题【dp】

很像贪心的dp啊 这个定金尾款的设定让我想起了lolita和jk制服的尾款地狱-- 设f[i][j]为从j到i的付定金的最早月份然后从f[k][j-1]转移来,两种转移f[i][j]=min(f[i][j],f[j-1][k]+1)是当前这个月付[k-1,j-1]的尾款和[j,i]的定金,f[i][j]=min(f[i][j],f[j-1][k]+2)是先付[k-1,j-1]的尾款,下个月再付[j,i]的定金 然后答案要+2,是最后一次付定金的尾款加上第一个月没有工资 #include<iost

General Problem Solving Techniques [Intermediate-1]~A - Children&#39;s Game

There are lots of number games for children. These games are pretty easy to play but not so easy to make. We will discuss about an interesting game here. Each player will be given N positive integer. (S)He can make a big integer by appending those in

【POJ 3265】Problem Solving

Problem Solving Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1645   Accepted: 675 Description In easier times, Farmer John's cows had no problems. These days, though, they have problems, lots of problems; they have P (1 ≤ P ≤ 300) pro

Volume 1. Elementary Problem Solving :: Sorting/SearchingUva 340,10420,10474,152,299,120,156,400,755

刘汝佳 算法入门 第一版 Uva题目集合(四) Uva 340 #include<stdio.h> #include<string.h> int h[1001][2],g[1001]={0}; int n,m=0,i,j,k,a,b,o; int main() { #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); freopen("output.txt","

poj3265(Problem Solving) dp

/*hdr ** Copyright ... ** AUTHOR MichaelMa ** DATE 4-May-2014 ** DESCRIPTION implement a mode of observer in C ** NOTE may be some bugs */ #include <stdio.h> #include <stdlib.h> #include <string.h> /***************************DEFINES****

hdu - 5349 MZL&#39;s simple problem(解题报告)

A - MZL's simple problem Time Limit:1500MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description A simple problem Problem Description You have a multiple set,and now there are three kinds of operations: 1 x : add number