寻找最小产品

时间:2016-02-20 21:26:17

标签: c++ algorithm

如何从阵列中找到最小的产品?这是我遇到的问题,并且尝试的解决方案不起作用。我做错了什么?

https://www.codechef.com/problems/CHRL4

  

在拜访了一个儿时的朋友后,厨师想回到他家。朋友住在第一条街上,厨师自己住在N - (也就是最后一条)街。他们的城市有点特别:当且仅当X时,您可以从Y街道移动到1 <= Y - X <= K街道,其中K是整数值这是给你的。厨师想以这样一种方式回家,即所有参观过的街道的产品。特殊数字很小(包括第一个和N - 街道)。请帮助他找到这样的产品。

     

输入

     

输入的第一行包含两个整数 - NK - 街道数量和K的值。第二行分别包含N个数字 - A1, A2, ..., AN,其中Ai等于i个街道的特殊数字。

     

输出

     

请输出最小可能产品的值,模1000000007。   约束

     

1 ≤ N ≤ 10^5   1 ≤ Ai ≤ 10^5   1 ≤ K ≤ N

     

示例

     

输入:

     

4 2   1 2 3 4。

     

输出:   8

#include <iostream>
using namespace std;

int P(int A[], int N, int K) {
    if (N == 1) return A[0];

    int m = A[0], prod = m;
    for (int i = 1; i < N; ++i) {
        if (1 <= A[i]-m && A[i]-m <= K) {
            prod *= A[i];
        }
    }
    return prod;
}

int main() {
    int A[] = {1, 2, 3, 4};
    cout << P(A, 4, 2);
}

我得到6而不是8。

1 个答案:

答案 0 :(得分:3)

这些问题通常可以通过动态编程来解决:

  1. 构造一个合适的状态变量:让状态为S = current street。让街道S上的因子被称为C_S
  2. 对于每个州S,请收集可能的操作:a(S) = {go to any street T for which : 1 <= C_T - C_S <= K, T <=N }, a(N) = {}
  3. 介绍一个价值函数V(S) = minimal product to get from S to N。设置V(N) = C_N
  4. 将所有这些结合在一起后,现在可以从N向后解决Bellman方程,其中特别寻求值V(0)

    V(S) = min_{allowed T} { V(T)*C_S }
    

    示例实施:

    int main()
    {
        int N = 4;
        int K = 2;
    
        std::vector<int> C{1,2,3,4};
        std::vector<int> V(N);
        V.back() = C.back();
    
        for(int i = N - 2; i>= 0; --i)
        {
            int min = std::numeric_limits<int>::max(); //possible overflow here,
                                                       //better change that
            for(int j=i+1; j< N; ++j)
            {
                double DeltaC = C[j] - C[i];
                if(DeltaC <= K && DeltaC >= 1)
                {
                    double vt = V[j] * C[i];
                    if(vt < min)
                    {
                        min = vt;
                    }
                }
            }
            V[i] = min;
        }
    
        std::cout<<V[0]<<std::endl;
    }
    

    DEMO

    输出为8

    请理解代码,测试它,然后用良心(无论这意味着什么)使用它。