zoukankan      html  css  js  c++  java
  • 【BJOI2019】排兵布阵 DP

    题目大意:有$n$座城堡,$s$轮游戏。

    对于第$x$轮,第i座城堡的士兵数量为$a[x][i]$。

    如果你需要攻下第i座城堡,你在第i座城堡部署的士兵必须严格大于$2a[x][i]$,如果攻下了你会获得$i$的收益。

    对于这$s$轮游戏,你只能采用一种部署方式。

    下面问你应该如何部署,使得你在这$s$轮游戏中的收益和最大。

    数据范围:$n,s≤100$,$m≤2000$。

    我们考虑直接$dp$,设$f[i][j]$表示前$i$个城堡部署了$j$名士兵的最大收益。

    不难发现,$f[i][j]=maxlimits_{k≤j,k∈a[][i]} f[i-1][j-k]+val[i][k]$。

    其中,$val[i][k]$表示你在第$i$城堡部署$k$个人的收益和。

    直接$dp$就可以了,复杂度为$O(nms)$。

     1 #include<bits/stdc++.h>
     2 #define M 105
     3 #define N 20005
     4 using namespace std;
     5 
     6 int f[M][N]={0},a[M][M]={0},val[M][M]={0};
     7 int s,n,m;
     8 
     9 int main(){
    10     scanf("%d%d%d",&s,&n,&m);
    11     for(int i=1;i<=s;i++)
    12     for(int j=1;j<=n;j++) scanf("%d",&a[i][j]);
    13     
    14     for(int i=1;i<=n;i++){
    15         for(int j=1;j<=s;j++){
    16             for(int k=1;k<=s;k++)
    17             if(a[j][i]>=a[k][i]) val[i][j]++;
    18         }
    19     }
    20     for(int i=1;i<=n;i++)
    21     for(int j=0;j<=m;j++){
    22         f[i][j]=f[i-1][j];
    23         for(int k=1;k<=s;k++)
    24         if(j>a[k][i]*2){
    25             f[i][j]=max(f[i][j],f[i-1][j-a[k][i]*2-1]+val[i][k]*i);
    26         }
    27     }
    28     int maxn=0;
    29     for(int i=1;i<=m;i++)
    30     maxn=max(maxn,f[n][i]);
    31     cout<<maxn<<endl;
    32 }
  • 相关阅读:
    数据库中的Convert
    xml Data Type Methods in sql server
    WITH common_table_expression (Transact-SQL)
    NuGet配置代理
    SQL Source Control
    3线-8线译码器
    git commit template
    PowerShell中和服务相关的命令
    how to backup and restore database of SQL Server
    上升时间最长的序列
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/10777638.html
Copyright © 2011-2022 走看看