有n头狼排成一排,每只狼两个属性,攻击力a(i)和加成值b(i)。
狼的实际攻击力等于自身攻击力加相邻狼的加成值。
被杀死之后的狼对相邻的狼的攻击力的加成会被取消,
同时,原先与 被杀死的狼相邻的两头狼会变成相邻的狼。
问杀死所有狼受到的伤害值最小是多少
数据范围:n<=200
区间dp,
令d[i][j]表示击杀[i,j]的所有狼所需要的最小代价,
转移方程:
枚举最后一只杀的狼k,d[i][j]=d[i][k-1]+d[k+1][j]+(a[k]+b[i-1]+b[j+1]).
解释一下转移方程:
先杀d[i][k-1]和d[k+1][j],
那么最后i-1,k,j+1相邻,杀k的代价为(a[k]+b[i-1]+b[j+1]).
#include
#define int long long
using namespace std;
const int maxm=205;
int d[maxm][maxm];
int a[maxm];
int b[maxm];
int n;
signed main(){
ios::sync_with_stdio(0);
int T;cin>>T;
int cas=1;
while(T--){
//input
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++)cin>>b[i];
b[n+1]=0;
//init
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
d[i][j]=1e18;
}
}
//dp
for(int i=1;i<=n;i++){
d[i][i]=a[i]+b[i-1]+b[i+1];
}
for(int len=2;len<=n;len++){
for(int i=1;i<=n;i++){
int j=i+len-1;
if(j>n)break;
for(int k=i;k<=j;k++){
d[i][j]=min(d[i][j],d[i][k-1]+d[k+1][j]+a[k]+b[i-1]+b[j+1]);
}
}
}
//output
cout<<"Case #"<<cas++<<": "<<d[1][n]<<endl;
}
return 0;
}