洛谷 P2214 [USACO14MAR]哞哞哞Mooo Moo
JDOJ 2416: USACO 2014 Mar Silver 3.Mooo Moo
Description
Problem 3: Mooo Moo [silver] [Brian Dean, 2014]
Farmer John has completely forgotten how many cows he owns! He is too
embarrassed to go to his fields to count the cows, since he doesn't want
the cows to realize his mental lapse. Instead, he decides to count his
cows secretly by planting microphones in the fields in which his cows tend
to gather, figuring that he can determine the number of cows from the total
volume of all the mooing he hears.
FJ's N fields (1 <= N <= 100) are all arranged in a line along a long
straight road. Each field might contain several types of cows; FJ
owns cows that come from B different breeds (1 <= B <= 20), and a cow
of breed i moos at a volume of V(i) (1 <= V(i) <= 100). Moreover,
there is a strong wind blowing down the road, which carries the sound
of mooing in one direction from left to right: if the volume of mooing
in some field is X, then in the next field this will contribute X-1 to
the total mooing volume (and X-2 in the field after that, etc.).
Otherwise stated, the mooing volume in a field is the sum of the
contribution due to cows in that field, plus X-1, where X is the total
mooing volume in the preceding field.
Given the volume of mooing that FJ records in each field, please compute
the minimum possible number of cows FJ might own.
The volume FJ records in any field is at most 100,000.
Input
* Line 1: The integers N and B.
* Lines 2..1+B: Line i+1 contains the integer V(i).
* Lines 2+B..1+B+N: Line 1+B+i contains the total volume of all mooing
in field i.
Output
* Line 1: The minimum number of cows owned by FJ, or -1 if there is no
configuration of cows consistent with the input.
Sample Input
5 2 5 7 0 17 16 20 19
Sample Output
4
HINT
INPUT DETAILS:
FJ owns 5 fields, with mooing volumes 0,17,16,20,19. There are two breeds
of cows; the first moos at a volume of 5, and the other at a volume of 7.
OUTPUT DETAILS:
There are 2 cows of breed #1 and 1 cow of breed #2 in field 2, and there is
another cow of breed #1 in field 4.
题目翻译:
约翰忘记了他到底有多少头牛,他希望通过收集牛叫声的音量来计算牛的数量。
他的N (1 <= N <= 100)个农场分布在一条直线上,每个农场可能包含B (1 <= B <= 20)个品种的牛,一头品种i的牛的音量是V(i) ,(1 <= V(i) <= 100)。一阵大风将牛的叫声从左往右传递,如果某个农场的总音量是X,那么将传递X-1的音量到右边的下一个农场。另外,一个农场的总音量等于该农场的牛产生的音量加上从上一个农场传递过来的音量(即X-1)。任意一个农场的总音量不超过100000。
请计算出最少可能的牛的数量。
题解:
完全背包问题的一个小变形。
设置dp[i] 为音量为i时最少的奶牛数量,所以最后的答案就是所有牧场自己的音量的总和。
注意,是实际音量,不是实际音量。
所以在原有a数组保存农场总音量的同时,我们引入了b数组来保存这个牧场的单纯音量。
注意,这里统计b数组的时候,一定要加max(和0比较),否则会WA3个点。
然后用maxx统计最大值,这样初始化的时候可以节省一点点时间。
然后就是振奋人心的DP过程啦!套用完全背包的模板的时候注意要加一个判断。
这个判断就是一种优化,emm,怎么说呢》自己体会吧!。
AC CODE:
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=1e9;
int n,B,maxx=-1,ans=0;
int v[25],a[105],b[105],dp[100005];
int main()
{
scanf("%d%d",&n,&B);
for(int i=1;i<=B;i++)
scanf("%d",&v[i]);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
b[i]=a[i]-max(a[i-1]-1,0);
maxx=max(maxx,b[i]);
}
for(int i=1;i<=maxx;i++)
dp[i]=INF;
for(int i=1;i<=B;i++)
for(int j=v[i];j<=maxx;j++)
if(dp[j-v[i]]!=INF)
dp[j]=min(dp[j],dp[j-v[i]]+1);
for(int i=1;i<=n;i++)
{
if(dp[b[i]]==INF)
{
printf("-1");
return 0;
}
ans+=dp[b[i]];
}
printf("%d",ans);
return 0;
}