题意:
有一排狼,每只狼有一个伤害A,还有一个伤害B。杀死一只狼的时候,会受到这只狼的伤害A和这只狼两边的狼的伤害B的和。如果某位置的狼被杀,那么杀它左边的狼时就会收到来自右边狼的B,因为这两只狼是相邻的了。求杀掉一排狼的最小代价。
解法:
设dp[i][j]为消灭i到j只狼的代价,枚举k作为最后一只被杀死的狼,此时会受到a[k]和b[i-1] b[j+1]的伤害 取最小的即可,[i,j]区间被分成三个部分[i,k-1],[k,k],[k+1,j];
可列出转移方程:dp[i][j]=Min(dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1])
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> using namespace std; #define inf 0x3f3f3f3f const int M=205; int a[M],b[M],dp[M][M]; int main() { int t,n,ca=1; scanf("%d%",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int len=0;len<n;len++) { for(int i=1;i+len<=n;i++) { int j=i+len; dp[i][j]=inf; for(int k=i;k<=j;k++) { dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]); // cout<<i<<" "<<j<<" "<<k<<" "<<dp[i][j]<<endl; } } } printf("Case #%d: %d ",ca++,dp[1][n]); } return 0; }