HDU 5653 Bomber Man wants to bomb an Array.(DP问题)

Bomber Man wants to bomb an Array.

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 556    Accepted Submission(s): 190


Problem Description
Given an array and some positions where to plant the bombs, You have to print the Total Maximum Impact.

Each Bomb has some left destruction capability L and some right destruction capability R which means if a bomb is dropped at ith location it will destroy L blocks on the left and R blocks on the right.
Number of Blocks destroyed by a bomb is L+R+1
Total Impact is calculated as product of number of blocks destroyed by each bomb.
If ith bomb destroys Xi blocks then TotalImpact=X1X2....Xm

Given the bombing locations in the array, print the Maximum Total Impact such that every block of the array is destoryed exactly once(i.e it is effected by only one bomb).

### Rules of Bombing
1. Bomber Man wants to plant a bomb at every bombing location.
2. Bomber Man wants to destroy each block with only once.
3. Bomber Man wants to destroy every block.

 

Input
There are multi test cases denote by a integer T(T20) in the first line.

First line two Integers N and M which are the number of locations and number of bombing locations respectivly.
Second line contains M distinct integers specifying the Bombing Locations.

1 <= N <= 2000

1 <= M <= N
 

Output
as Maximum Total Impact can be very large print the floor(1000000 * log2(Maximum Total Impact)).

Hint:
Sample 1:



Sample 2:

 

Sample Input
2 10 2 0 9 10 3 0 4 8
 

Sample Output
4643856 5169925
 

Source

Bomber Man wants to bomb an Array.

 
 Accepts: 56
 
 Submissions: 225
 Time Limit: 4000/2000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
给一个长度为 NN 的一维格子和一些炸弹的位置,请你计算 “最大总破坏指数”。

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

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



题意:有一行n个的格子,其中m个格子有炸弹,然后炸弹可以向左向右炸,范围自定义,但是不能重复炸同一个格子。然后每个炸弹对应一个炸的格子数,所有炸弹的对应格子数乘积,然后运算一下。


思路:DP求解,对于每个炸弹,可以炸的范围L,R是不确定的,但是一定在左右两个炸弹所在位置范围内,所以可以枚举一下可以炸的范围,dp[i]用来记录对于第i个位置,累计可以得到的最大值。


#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#define ll __int64
#define MOD 1000000007
using namespace std;

int a[2222];
double dp[2222];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        memset(dp,0,sizeof dp);

        for(int i=1; i<=m; i++)
        {
            scanf("%d",&a[i]);
            a[i]++;
        }
        sort(a+1,a+m+1);

        a[m+1]=n+1;
        for(int i=1; i<=m; i++)
        {
            for(int j=a[i-1]+1; j<=a[i]; j++)
            {
                for(int k=a[i]; k<=a[i+1]-1; k++)
                {
                    dp[k]=max(dp[k],dp[j-1]+(log(k-j+1.0)/log(2.0)));
                }
            }
        }

        ll ans=floor(1e6*dp[n]);
        printf("%I64d\n",ans);
    }
    return 0;
}
















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章