BestCoder Round #77 (div.1) Bomber Man wants to bomb an Array. Hdu5653

来源:互联网 发布:惠人e8wn m是网络款吗 编辑:程序博客网 时间:2024/05/15 13:26

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

每个炸弹都有向左和向右的破坏力,如果一个炸弹向左和向右的破坏力分别为 和 R,

那么该炸弹将炸毁 L + R + 1个格子(左边L个,炸弹所在格子,右边R个)。

破坏指数的计算方式为:所有炸弹炸毁的格子数的乘积。假设第 个炸弹炸毁了 X_i个格子,

那么总破坏指数就是 X_1 * X_2 * .... X_m

现在告诉你每个炸弹的位置,你需要计算 最大的总破坏指数,注意:每个格子最多只允许被炸一次。(n<=2000)


思路:dp,dp[i][j]表示到了第i个位置,该位置选择的R的位置为j,那么状态转移方程为dp[i][j]=max(dp[i-1][k]+log2(k-j)),k表示第i-1个位置选择的R的位置。


#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn=2001;double dp[2][maxn];int a[maxn];int main(){    int _,n,m;    scanf("%d",&_);    while(_--){        scanf("%d%d",&n,&m);        for(int i=1;i<=m;i++)            scanf("%d",&a[i]),a[i]++;        sort(a+1,a+m+1);        a[0]=0,a[m+1]=n+1;        memset(dp,0,sizeof(dp));        int flag=0;        for(int i=1;i<=m;i++){            for(int j=a[i-1];j<=a[i]-1;j++)//上一个的右边                for(int k=a[i];k<=a[i+1]-1;k++)//这一个的右边                    dp[flag^1][k]=max(dp[flag^1][k],dp[flag][j]+log(k-j)/log(2));            flag^=1;        }        printf("%lld\n",(long long)floor(dp[flag][n]*1000000));    }    return 0;}


0 0
原创粉丝点击