P2214 题解
分析
这道题可以转化为完全背包,设当前位置为
若
否则,当前位置多出的音量为
特别的,当
把当前位置多出的音量当做背包容量,设第
得到状态转移方程如下:
-
f[j]=\min(f[j],f[j-v[i]]+1)
每个位置跑一次背包,答案累加即可。
若存在某个位置没有答案,则输出
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+5,INF=0x3f3f3f3f;
int v[21],f[N],sumV,ans;
int n,b;
int main(){
int i,j,k;
scanf("%d%d",&n,&b);
for(i=1;i<=b;i++) scanf("%d",&v[i]);
int tmp=0;//记录上个位置的音量
for(i=1;i<=n;i++){
int x;
scanf("%d",&x);
sumV=0;
if(tmp==0) sumV=x;
else if(tmp-1<x) sumV=x-(tmp-1);
tmp=x;
for(j=1;j<=sumV;j++) f[j]=INF;
f[0]=0;//记得初始化
for(j=1;j<=b;j++)
for(k=v[j];k<=sumV;k++)
f[k]=min(f[k],f[k-v[j]]+1);//完全背包
if(f[sumV]==INF){
printf("-1\n");
return 0;
}
ans+=f[sumV];
}
printf("%d\n",ans);
return 0;
}