您的位置:首页 > 其它

HDU5653 Bomber Man wants to bomb an Array. DP

2016-03-27 14:16 344 查看

Bomber Man wants to bomb an Array.

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 246 Accepted Submission(s): 82



[align=left]Problem Description[/align]
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=X1∗X2∗....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.

[align=left]Input[/align]
There are multi test cases denote by a integer
T(T≤20)
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

[align=left]Output[/align]
as Maximum Total Impact can be very large print the floor(1000000 * log2(Maximum Total Impact)).

Hint:

Sample 1:



Sample 2:



[align=left]Sample Input[/align]

2
10 2
0 9
10 3
0 4 8


[align=left]Sample Output[/align]

4643856
5169925


[align=left]Source[/align]
BestCoder Round #77 (div.2)

考虑DP,设dp[i][j]=序列位置i到j能得到的最大的破坏值(是log2之后的值)

dp[i][j]=max(dp[i][j],log2[k-i]+dp[k][j]) i<k<=j 并且保证[i,k-1],[k,j]内都有炸弹。

记忆化搜索一下。

还有就是log2函数速度有点慢,所以要预处理出[1,2000]以内的log2值Log2[],不然会TLE。

/****************
*PID:hdu5653
*Auth:Jonariguez
*****************
事实证明Log2太慢,需要预处理。
*/
#define lson k*2,l,m
#define rson k*2+1,m+1,r
#define rep(i,s,e) for(i=(s);i<=(e);i++)
#define For(j,s,e) For(j=(s);j<(e);j++)
#define sc(x) scanf("%d",&x)
#define In(x) scanf("%I64d",&x)
#define pf(x) printf("%d",x)
#define pfn(x) printf("%d\n",(x))
#define Pf(x) printf("%I64d",(x))
#define Pfn(x) printf("%I64d\n",(x))
#define Pc printf(" ")
#define PY puts("YES")
#define PN puts("NO")
#include <stdio.h>
#include <string.h>
#include <string>
#include <math.h>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef int Ll;
Ll quick_pow(Ll a,Ll b,Ll MOD){a%=MOD;Ll res=1;while(b){if(b&1)res=(res*a)%MOD;b/=2;a=(a*a)%MOD;}return res;}

const int maxn=2000+10;
const double INF=1000000;
int vis[maxn][maxn],p[maxn],sum[maxn];
double dp[maxn][maxn],Log2[maxn];
double DP(int x,int y){
if(x>=y) return 0;
if(vis[x][y]) return dp[x][y];
vis[x][y]=1;
double &ans=dp[x][y];
ans=0;
if(sum[y]-sum[x-1]==1)
return ans=Log2[y-x+1];
int cnt=0,i=x;
while(p[i]==0) i++;
if(i>y) return ans=-INF;     //区间内无炸弹则返回负无穷
i++;
for(;i<=y;i++){
ans=max(ans,Log2[i-x]+DP(i,y));
if(p[i]) break;          //[x,i-1]内保证只有一个炸弹,所以再次遇到炸弹则停止,下同。
}
i=y;
while(p[i]==0) i--;
i--;
for(;i>=x;i--){
ans=max(ans,Log2[y-i]+DP(x,i));
if(p[i]) break;
}
return ans;
}

int main()
{
int i,j,n,T;
for(i=1;i<=2001;i++)
Log2[i]=log2(i);
scanf("%d",&T);
while(T--){
int m;
sc(n);sc(m);
memset(vis,0,sizeof(vis));
memset(p,0,sizeof(p));
for(i=1;i<=m;i++){
int x;
sc(x);x++;
p[x]=1;
}
sum[0]=0;
for(i=1;i<=2001;i++)
sum[i]=sum[i-1]+p[i];
double res=DP(1,n);
printf("%I64d\n",(LL)floor(1000000.0*res));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: