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;
}
















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