hdoj 5653 Bomber Man wants to bomb an Array. 【dp】

题目链接:hdoj 5653 Bomber Man wants to bomb an Array.

问题描述
给一个长度为 N 的一维格子和一些炸弹的位置,请你计算 “最大总破坏指数”。

每个炸弹都有向左和向右的破坏力,如果一个炸弹向左和向右的破坏力分别为 LL 和 RR,
那么该炸弹将炸毁 L + R + 1个格子(左边L个,炸弹所在格子,右边R个)。
破坏指数的计算方式为:所有炸弹炸毁的格子数的乘积。假设第 i个炸弹炸毁了 X_i个格子,那么总破坏指数就是 X_1 * X_2 * …. X_m 。

现在告诉你每个炸弹的位置,你需要计算 最大的总破坏指数,注意:每个格子最多只允许被炸一次。
输入描述
多组测试数据,第一行为一个整数T(T≤11)。
每组测试数据第一行为两个整数 N,M(1≤N≤2000,1≤M≤N),分别表示格子总数和炸弹总数 。第二行是 MM 个互不相同的数表示每个炸弹所在的位置。
输出描述
对于每组测试数据,输出 floor(10^6 * log2(最大破坏指数)) (floor表示向下取整)。
输入样例
2
10 2
0 9
10 3
0 4 8
输出样例
4643856
5169925
Hint
Sample 1 :

Sample 2:

思路: dp[i][j] 表示处理到第 i 个炸弹,炸到第j个位置的最大破坏指数。最后结果会超long long——2000取50个,结果 = 4050 ,可怕。。。

AC 代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#define PI acos(-1.0)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define fi first
#define se second
#define ll o<<1
#define rr o<<1|1
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int MAXN = 2*1e3 + 10;
const int pN = 1e6;// <= 10^7
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
void add(LL &x, LL y) { x += y; x %= MOD; }
double dp[MAXN][MAXN];
int a[MAXN];
int main()
{
    int t; scanf("%d", &t);
    while(t--) {
        int n, m; scanf("%d%d", &n, &m);
        for(int i = 1; i <= m; i++) {
            scanf("%d", &a[i]); a[i]++;
        }
        sort(a+1, a+m+1); CLR(dp, 0);
        a[m+1] = n+1;
        for(int i = 1; i <= m; i++) {
            if(i == 1) {
                for(int j = a[i]; j < a[i+1]; j++) {
                    dp[i][j] = log2(j);
                }
            }
            else {
                for(int j = a[i]; j < a[i+1]; j++) {
                    for(int k = a[i-1]; k < a[i]; k++) {
                        dp[i][j] = max(dp[i][j], dp[i-1][k] + log2(j - k));
                    }
                }
            }
        }
        //cout << dp[m][n] << endl;
        cout << (LL)(1e6 * dp[m][n]) << endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值