(紀中)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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章