zoukankan      html  css  js  c++  java
  • 【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) problems, to be exact. They have quit providing milk and have taken regular jobs like all other good citizens. In fact, on a normal month they make M (1 ≤ M ≤ 1000) money.

    Their problems, however, are so complex they must hire consultants to solve them. Consultants are not free, but they are competent: consultants can solve any problem in a single month. Each consultant demands two payments: one in advance (1 ≤ payment ≤ M) to be paid at the start of the month problem-solving is commenced and one more payment at the start of the month after the problem is solved (1 ≤payment ≤ M). Thus, each month the cows can spend the money earned during the previous month to pay for consultants. Cows are spendthrifts: they can never save any money from month-to-month; money not used is wasted on cow candy.

    Since the problems to be solved depend on each other, they must be solved mostly in order. For example, problem 3 must be solved before problem 4 or during the same month as problem 4.

    Determine the number of months it takes to solve all of the cows' problems and pay for the solutions.

    Input

    Line 1: Two space-separated integers: M and P
    Lines 2..P+1: Line i+1 describes problem i with two space-separated integers: Bi and AiBi is the payment to the consult BEFORE the problem is solved; Ai is the payment to the consult AFTER the problem is solved. 

    Output

    Line 1: The number of months it takes to solve and pay for all the cows' problems.

    Sample Input

    100 5
    40 20
    60 20
    30 50
    30 50
    40 40

    Sample Output

    6

    Hint

    +------+-------+--------+---------+---------+--------+
    |      | Avail | Probs  | Before  | After   | Candy  |
    |Month | Money | Solved | Payment | Payment | Money  |
    +------+-------+--------+---------+---------+--------+
    | 1    | 0     | -none- | 0       | 0       | 0      |
    | 2    | 100   | 1, 2   | 40+60   | 0       | 0      |
    | 3    | 100   | 3, 4   | 30+30   | 20+20   | 0      |
    | 4    | 100   | -none- | 0       | 50+50   | 0      |
    | 5    | 100   | 5      | 40      | 0       | 60     |
    | 6    | 100   | -none- | 0       | 40      | 60     | 
    +------+-------+--------+---------+---------+--------+

    Source

     
    一道简单的动态规划题目。
    设f[n]为答案。
    枚举j,表示j~i这几个问题在同一个月内完成(如果可以),那么很明显有两种情况,做完j-1个问题的最小月数是f[j-1],下个月要付before[j-1]的钱。
      (1)before[j-1] + sigma{a[k] | j <= k <= i} <= M,那么这样的最小值就是,f[j - 1]+1了;
      (2)before[j-1] + sigma{a[k] | j <= k <= i} > M,那么很明显不能和上面的问题直接接上去了,f[j-1]+2;
    时间复杂度O(N2)。
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    int m, p, a[305], b[305];
    int f[305], before[305];
    
    int main()
    {
        scanf("%d%d", &m, &p);
        for (int i = 1; i <= p; ++i)
            scanf("%d%d", &a[i], &b[i]);
        before[0] = a[0] = 300005;
        f[0] = 1;
        for (int i = 1; i <= p; ++i)
        {
            int suma = 0, sumb = 0;
            f[i] = f[i - 1] + 2;
            before[i] = b[i];
            for (int j = i; j >= 1; --j)
            {
                suma += a[j];
                sumb += b[j];
                if (suma > m || sumb > m) break;
                if (suma + before[j - 1] <= m && f[j - 1] + 1 <= f[i])
                {
                    if (f[j - 1] + 1 == f[i]) before[i] = min(before[i], sumb);
                    else before[i] = sumb;
                    f[i] = f[j - 1] + 1;
                }
                if (suma + before[j - 1] > m && f[j - 1] + 2 <= f[i])
                {
                    if (f[j - 1] + 2 == f[i]) before[i] = min(before[i], sumb);
                    else before[i] = sumb;
                    f[i] = f[j - 1] + 2;
                }
            }
        }
        printf("%d
    ", f[p]);
        return 0;
    }
  • 相关阅读:
    计算机网络知识技能水平的测评试题
    Socket与系统调用深度分析
    学习构建调试Linux内核网络代码的环境MenuOS系统
    深入学习socket网络编程,以java语言为例
    网络配置工具iproute2和net-tools的基本原理和基本使用方法
    Linux系统学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用-40号调用
    基于mykernel2.0 编写一个操作系统内核
    交互式多媒体图书平台的设计与实现
  • 原文地址:https://www.cnblogs.com/albert7xie/p/4840859.html
Copyright © 2011-2022 走看看