(纪中)1932. 奶牛的声音(mooomoo)【DP(完全揹包)】

*(File IO): input:mooomoo.in output:mooomoo.out
时间限制: 1000 ms 空间限制: 128000 KB 具体限制 *


题目描述
农夫约翰最近忘记他有多少奶牛了!于是他决定用一个特别新颖的方法来计算奶牛的数量。他在每块农田上都安装一个麦克风,通过麦克风的音量来计算每个农田上有多少奶牛。
约翰的N个农田是排成一条直线,每个农田上可能拥有不同种类的奶牛,奶牛的种类是BB种,第i种奶牛每只奶牛都会发出ViV_i的音量。然后,由于农场里是经常有风的,风的方向是从左到右的,风使得奶牛的声音也从左到右吹了过去。如果声音在某块农田的音量是XX,那么接下来风将把X1X-1音量的声音带到下一个(右边)那个农田上去。因此每块农田上的音量等于本身这块农田上奶牛发出的声音加上左边相邻的农田音量X1X-1
给定从左到右每块农田上的音量,请帮助约翰计算他最少有多少数量的奶牛。


输入
第一行两个正整数N和B。
22行到第B+1B+1行,第i+1i+1行的整数表示ViV_i
B+2B+2行到第B+i+1B+i+1行,表示从左到右每块农田上的监测到的音量。

输出
输出最少可能有多少奶牛,如果不能确定的话,就输出1-1


样例输入
5 2
5
7
0
17
16
20
19

样例输出
4


数据范围限制
1<=N<=100,1<=B<=20,1<=Vi<=1001<=N<=100,1<=B<=20,1<=Vi<=100,每块农田上监测的音量不超过100000100000


提示
第一块农田上音量为00,所以奶牛数量也为00,第二块农田上音量为1717,由于左边没有声音传过来,所以1717的音量全部是第二块农田上奶牛产生的,第二块农田上最少有22只第11种类的奶牛和11只第22种类的奶牛,接下来第三块农田上的音量是1616,全部由左边传过来,所以第三块农田没有奶牛,第四块农田上音量是2020,其中1515是由第三块农田上传过来的,55是自己产生的,55的音量最少有1只第一种类的奶牛,所以最少总共有44只奶牛。


解题思路
题目大意:
奶牛的声音从左吹到右,逐次1-1累加,有bb种奶牛,第i种奶牛每只奶牛都会发出ViV_i的音量,最少可能有多少奶牛。
这是一个完全揹包的方案数问题,动态规划转移方程为
f[j+v[i]]=min(f[j]+1,f[j+v[i]])f[j+v[i]]=min(f[j]+1,f[j+v[i]])f[i]f[i]表示音量为ii时的方案数。


代码

#include<bits/stdc++.h>
using namespace std;
int n,b,f[100010],a[25],x,s,ans;
int main()
{
	freopen("mooomoo.in","r",stdin);
    freopen("mooomoo.out","w",stdout);
    scanf("%d%d",&n,&b);
    for(int j=0; j<=100005; j++)
        f[j]=2147480000;
	f[0]=0;
    for(int i=1; i<=b; i++)
        scanf("%d",&a[i]);
    for(int i=1; i<=n; i++)
        for(int j=a[i]; j<=100000; j++)
            f[j]=min(f[j-a[i]]+1,f[j]);
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&x);
        if(x==0)continue;
        if(s<=x&&f[x-s]!=2147480000)
            ans+=f[x-s];
        else 
        {
            printf("-1");
            return 0;
        }
        s=x-1;
    }
    printf("%d",ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章