HDU 5115 Dire Wolf

来源:互联网 发布:北京11选5遗漏数据查询 编辑:程序博客网 时间:2024/05/18 03:07

上次北京赛现场赛的题了,昨天做了道区间dp,突然想起来这道题,都是很类似的,就翻出来做了做

刚开始像昨天做的那道一样,老想着怎么逆推,后来发现这道题应该正着推

其实正推和逆推乍看起来是很相似的,只不过一个是dp[i][j]表示i、j左右还有其他狼时消灭掉i-j这段消耗的费用,一个是表示最后只剩i-j时消灭掉这段的费用

总结一下昨天那道区间dp和今天的区间dp的相同点,发现区间dp适用于费用会随着时间的推移,或者说dp的进行不断变化

#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;const int inf=999999999;int a[205],b[205];int dp[205][205],n;void init(){for(int i=0;i<205;i++){for(int j=0;j<205;j++){dp[i][j]=inf;}}b[n+1]=0;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++) dp[i][i+1]=min(dp[i][i]+a[i+1]+b[i+2]+b[i-1],dp[i+1][i+1]+a[i]+b[i-1]+b[i+2]);}int main() {#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endifint T;scanf("%d",&T);int cas=1;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]);}init();for(int l=3;l<=n;l++){for(int i=1;i+l-1<=n;i++){int j=i+l-1;dp[i][j]=min(dp[i][j],dp[i+1][j]+a[i]+b[i-1]+b[j+1]);dp[i][j]=min(dp[i][j],dp[i][j-1]+a[j]+b[j+1]+b[i-1]);for(int k=i+1;k<=j-1;k++){dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+b[i-1]+b[j+1]+a[k]);}//printf("dp[%d][%d] :%d\n",i,j,dp[i][j]);}}printf("Case #%d: %d\n",cas++,dp[1][n]);}}


0 0
原创粉丝点击