当我尝试提交mkbudget spoj时获得WA

时间:2012-03-22 03:48:27

标签: c++ algorithm dynamic-programming

我无法理解/想到我的代码无法提供正确输出的情况。 链接到问题:http://www.spoj.pl/problems/MKBUDGET/

问题显然有DP解决方案。我在下面发布我的解决方案:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

vector<vector <int> > opt;

void compute_opt(vector<int> A,int n,int hire,int fire,int sal,int max_a)
{
    for(int i = A[0]; i <= max_a; i++)  //for num workers in 1st month
        opt[0][i] = i*(hire + sal);

    for(int i = 1; i < n; i++)  //num of months
        for(int j = A[i]; j <= max_a; j++)  //num of workers for ith month >=A[i] and <= max_a
            {
                opt[i][j] = opt[i-1][A[i-1]] + j*sal + (A[i] > A[i-1] ? (A[i]-A[i-1])*hire : (A[i-1] - A[i])*fire);

                for(int k = A[i-1]; k <= max_a; k++)
                    opt[i][j] = min(opt[i][j], opt[i-1][k] + j*sal + (j>k ? (j-k)*hire : (k-j)*fire));
            }   
}

int ans(vector<int> A, int n, int max_a)
{
    int ret = opt[n-1][A[n-1]];
    for(int i = A[n-1]; i <= max_a; i++)
        ret = min (ret, opt[n-1][i]);

    return ret; 
}

int main()
{
    vector<int> A;
    int n, hire, fire, sal,max_a, c = 1;
    while(1)
    {
        cin >> n;
        if(n == 0)
            break;

        A.clear();
        opt.clear();
        max_a = 0;
        cin >> hire >> sal >> fire;
        A.resize(n);
        for(int i = 0; i < n; i++)  
            {cin >> A[i];
             max_a = max(max_a,A[i]);
             }

        opt.resize(n);  
        for(int i = 0; i < n; i++)
            opt[i].resize(max_a + 2);

        compute_opt(A,n,hire,fire,sal,max_a);
        cout << "Case " << c << ", cost = $" << ans(A,n,max_a) << endl;
        c++;
    }
    return 0;
}

我得到了两个样本测试用例的正确答案,但是当我提交时我得到了一个WA。有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

好的,所以你的问题是你不允许在A [i]和A [i - 1]之间聘用任意数量的雇员。也许解雇一些不需要的员工是个好主意,但不是全部。这就是你获得WA的原因。我修改了你的代码并接受了它:

void compute_opt(vector<int> A,int n,int hire,int fire,int sal,int max_a)
{
    // Fill all disallowed entries with infinity
    for (int i = 0; i < A[0]; ++i)
        opt[0][i] = 1000000000;
    for(int i = A[0]; i <= max_a; i++)  //for num workers in 1st month
        opt[0][i] = i*(hire + sal);

    for(int i = 1; i < n; i++)
        for(int j = 0; j <= max_a; j++)
            {
                // No need for special case handling,
                //just check all previous numbers of employees
                opt[i][j] = 1000000000;
                if (A[i] > j) continue;
                for(int k = 0; k <= max_a; k++)
                    opt[i][j] = min(opt[i][j],
                       opt[i-1][k] + j*sal + (j>k ? (j-k)*hire : (k-j)*fire));
            }   
}

顺便说一下,有一个“贪婪”的解决方案,而不是那个不依赖于员工数量的员工(这样可以分配表)。