USACO Stamps, DP

来源:互联网 发布:淘宝卖家发货后消失 编辑:程序博客网 时间:2024/05/16 11:34

思路:

状态:设F[i]为组成面值为i所需要的最少的邮票数量
初始:F[0]=0
状态转移方程:
F[i]=min{F[ i-value[j] ] (j=1..n and i-value[j]>=0) }+1
最终答案:找到最小的F[i]>k,则答案为(i-1)

解析:F[i]具有最有子策略,即F[i]由F[0..i-1]中特定的最优解决定。枚举每种邮票j,F[ i-value[j] ]为若F[i]中有邮票j,它就是不贴邮票j时,组成面值为i-value[j]所需要的邮票数量的最小值。为使F[i]为最优解,应取F[ i-value[j] ]构成的集合中的元素的最小值,并加1,表示选取了j这张邮票。

时间复杂度(最坏情况):O(mnk) (m为每种邮票的面值最大值)


我的代码,注意这题的MAX要设定到2000000,因为这个出现了signal #11号错误好多次……
/* ID: wangxin12 PROG: stampsLANG: C++ */ #include <iostream>#include <vector>#include <fstream>#include <queue>using namespace std;#define MAX 2000000int K, N; // K <= 200, N <= 50vector<int> cents;int dp[MAX + 1];int main() {ifstream fin("stamps.in");ofstream fout("stamps.out");int i, j;fin>>K>>N;for(i = 1; i <= N; i++) {fin>>j;cents.push_back(j);}::QuickSort(cents, 0, cents.size() - 1);//init 初始状态for(i = 1; i <= MAX; i++)dp[i] = MAX;i = 1; while( i ) {int minCost = MAX;for(j = 1; j <= N; j++) {if(i >= cents[j - 1]) {int temp = dp[ i - cents[j - 1] ] + 1;if(temp < minCost)minCost = temp;}}dp[i] = minCost;if(dp[i] > K) break;i++;}for(i = 1;  ; i++) {if(dp[i] == 0 || dp[i] > K)break;}fout<<i - 1<<endl;return 0;}


--------------------------------------------------------------------------------------------------

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 21 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

描述

已知一个 N 枚邮票的面值集合(如,{1 分,3 分})和一个上限 K —— 表示信封上能够贴 K 张邮票。计算从 1 到 M 的最大连续可贴出的邮资。

例如,假设有 1 分和 3 分的邮票;你最多可以贴 5 张邮票。很容易贴出 1 到 5 分的邮资(用 1 分邮票贴就行了),接下来的邮资也不难:

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

然而,使用 5 枚 1 分或者 3 分的邮票根本不可能贴出 14 分的邮资。因此,对于这两种邮票的集合和上限 K=5,答案是 M=13。

[规模最大的一个点的时限是3s]


小提示:因为14贴不出来,所以最高上限是13而不是15


原创粉丝点击