题解 P2214 【[USACO14MAR]哞哞哞Mooo Moo】
难得的DP大水题,没想到只有这么点人AC。类似于完全背包。
dp[i]代表音量为i时最小的牛的数量,即可列出DP状态转移方程:dp[i]=min(dp[i],dp[i-当前枚举到的牛的音量大小]+1);
然后算出每个田地的实际音量,累加即可。但是不要忘了打“-1”啊!
详见代码:【CPP】(本蒟蒻自认为比楼下写的清晰,明了,好理解2333)
const int INF=2147483647;
int n,k,mx=-1,ans=0;
int v[25],a[105],b[105],dp[100005];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=k;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);//每个田地的实际音量
mx=max(mx,b[i]);//记录最大音量,一点点优化。
}
//dp
for(int i=1;i<=mx;i++)dp[i]=INF;//初始化
for(int i=1;i<=k;i++)
{
for(int j=v[i];j<=mx;j++)
{
if(dp[j-v[i]]!=INF)dp[j]=min(dp[j],dp[j-v[i]]+1);//一定要判断dp[j-v[i]]!=INF,不然会炸掉!
}
}
for(int i=1;i<=n;i++)
{
if(dp[b[i]]==INF)
{
printf("-1\n");//别忘啦!
return 0;
}
ans+=dp[b[i]];//累加求解
}
printf("%d\n",ans);
return 0;
}
//此题难度是:提高+/省选-?!确定?!明明是普及+/提高-差不多