HDU - 5115 Dire Wolf(区间dp)
题意:n只狼,每只狼有自己的攻击力,同时也会受到相邻狼的加成,问杀死n只狼后受到的最少攻击。
分析:区间dp。
定义状态 dp[i][j]为第i只到第j只狼都被杀了后受到的最少攻击。
那么 dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+a[k]+b[i-1]+b[j+1]) (i<k<j).枚举区间,然后枚举这个区间里的任意一只狼,杀了它,此时区间内其他狼都已被杀。注意初始化。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<stack> #include<vector> #include<cstdlib> #include<climits> #include<ctype.h> #include<set> #include<map> #define pi acos(-1.0) #define mem(a) memset(a,0,sizeof(a)) #define mems(a,b) memset((a),(b),sizeof(a)) #define ll long long #define ull unsigned long long //#define LOCAL #define ls root<<1 #define rs root<<1|1 #define Ls root<<1,l,mid #define Rs root<<1|1,mid+1,r using namespace std; const int maxn=(1<<20); const int inf=0x3f3f3f3f; const int INF=0x3f3f3f3f3f3f3f3f; const int mod=1e9+7; int dp[250][250]; int a[250],b[250]; int main() { //ios::sync_with_stdio(false); #ifdef LOCAL freopen("data","r",stdin); // freopen("out","w",stdout); #endif int t,n,m,cas=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]); a[0]=a[n+1]=b[0]=b[n+1]=0; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) dp[i][i]=a[i]+b[i-1]+b[i+1]; // for(int i=1;i<=n;i++) printf("%d ",dp[i][i]);puts(""); for(int j=2;j<=n;j++){ for(int i=1;i<=n-j+1;i++){ int k=i+j-1; dp[i][k]=min(dp[i][k-1]+a[k]+b[k+1]+b[i-1],dp[i+1][k]+a[i]+b[k+1]+b[i-1]); for(int l=i+1;l<k;l++){ dp[i][k]=min(dp[i][l-1]+dp[l+1][k]+a[l]+b[i-1]+b[k+1],dp[i][k]); } } } printf("Case #%d: %d\n",cas++,dp[1][n]); } return 0; }