HDU5115 Dire Wolf(区间DP)

 

渐渐认识到区域赛更侧重的是思维及基本算法的灵活运用,而不是算法的量(仅个人见解),接下来要更多侧重思维训练了。

 

区间DP,dp[i][j]表示从i到j最终剩余第i 与第j只的最小伤害值,设置0与n+1两个虚拟的狼,状态转移方程如下:

dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + b[i] + b[j])

 

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
#include<utility>
using namespace std;
typedef long long LL;
const int N = 208, INF = 0x3F3F3F3F;
#define MS(a, num) memset(a, num, sizeof(a))
#define PB(A) push_back(A)
#define FOR(i, n) for(int i = 0; i < n; i++)
int a[N], b[N];
int dp[N][N];
int main(){
    int t;
    cin>>t;
    for(int cas = 1; cas <= t; cas++){
        int n;
        scanf("%d", &n);
        int sum = 0;
        for(int i = 1; i <= n; i++){
            scanf("%d", &a[i]);
            sum += a[i];
        }
        for(int i = 1; i <= n; i++){
            scanf("%d", &b[i]);
        }
        b[n + 1] = b[0] = 0;
        memset(dp, 0x3F, sizeof(dp));

        for(int i = 0 ; i <= n + 1; i++){
            dp[i][i] = 0;
            dp[i][i + 1] = 0;
        }
        for(int len = 3;len <= n + 2; len++){
            for(int i = 0, j = len - 1; j <= n + 1; i++, j++){
                for(int k = i + 1; k < j; k++){
                    dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + b[i] + b[j]);
                }
            }
        }
        printf("Case #%d: %d\n", cas, dp[0][n + 1] + sum);
    }
    return 0;
}

  

posted @ 2016-08-07 18:22  vwirtveurit  阅读(301)  评论(0编辑  收藏  举报