Stamps(DP)

Stamps

Given a set of N stamp values (e.g., {1 cent, 3 cents}) and an upper limit K to the number of stamps that can fit on an envelope, calculate the largest unbroken list of postages from 1 cent to M cents that can be created.

For example, consider stamps whose values are limited to 1 cent and 3 cents; you can use at most 5 stamps. It's easy to see how to assemble postage of 1 through 5 cents (just use that many 1 cent stamps), and successive values aren't much harder:

  • 6 = 3 + 3
  • 7 = 3 + 3 + 1
  • 8 = 3 + 3 + 1 + 1
  • 9 = 3 + 3 + 3
  • 10 = 3 + 3 + 3 + 1
  • 11 = 3 + 3 + 3 + 1 + 1
  • 12 = 3 + 3 + 3 + 3
  • 13 = 3 + 3 + 3 + 3 + 1.

However, there is no way to make 14 cents of postage with 5 or fewer stamps of value 1 and 3 cents. Thus, for this set of two stamp values and a limit of K=5, the answer is M=13.

The most difficult test case for this problem has a time limit of 3 seconds.

PROGRAM NAME: stamps

INPUT FORMAT

Line 1: Two integers K and N. K (1 <= K <= 200) is the total number of stamps that can be used. N (1 <= N <= 50) is the number of stamp values.
Lines 2..end: N integers, 15 per line, listing all of the N stamp values, each of which will be at most 10000.

SAMPLE INPUT (file stamps.in)

5 2
1 3

OUTPUT FORMAT

Line 1: One integer, the number of contiguous postage values starting at 1 cent that can be formed using no more than K stamps from the set.

SAMPLE OUTPUT (file stamps.out)

13

 

      题意:

      给出 K(1 ~ 200) 和 N(1 ~ 50),代表只能使用任意的 K 个数,有 N 种数选择,后给出 N 个数,输出一个最大的上限,使凑到 1 ~ M 中的任意一个数,只能用 K 个数且必须是 N 种数里面。

 

      思路:

      DP。dp [ i ] 代表能凑到 i 钱币的最少使用张数,当一遇到凑不到的情况就退出循环。

      递推式子 dp [ i ] = min { dp [ i ] , dp [  i - mon [ j ] ] + 1 }。

 

      AC:

/*
TASK:stamps
LANG:C++
ID:sum-g1
*/

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int MAX = 3000005;
const int INF = 9999999;

int dp[MAX], mon[55];

void init() {
    for (int i = 0; i < MAX; ++i)
        dp[i] = INF;
    dp[0] = 0;
}

int main() {
    freopen("stamps.in", "r", stdin);
    freopen("stamps.out", "w", stdout);

    init();
    int k, n;
    scanf("%d%d", &k, &n);

    for (int i = 0; i < n; ++i)
        scanf("%d", &mon[i]);

    for (int i = 1; i < MAX; ++i) {
        for (int j = 0; j < n; ++j) {
            if (i - mon[j] >= 0 && (dp[i - mon[j]] + 1) <= k) {
                dp[i] = min(dp[i], dp[i - mon[j]] + 1);
            }
        }

        if(dp[i] == INF) {
            printf("%d\n", i - 1);
            break;
        }
    }

    return 0;
}

 

 

 

你可能感兴趣的:(dp)