• 【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]=\max\limits_{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 }
  • 相关阅读:
    四则运算2
    大二第二学期阅读计划
    第一周课堂练习
    《人月神话》读后感
    软件工程概论总结第十一章
    软件工程概论总结第十章
    软件工程概论总结第九章
    软件工程概论总结第八章
    软件工程概论总结第七章
    第五章、软件过程中的形式化方法
  • 原文地址:https://www.cnblogs.com/alphainf/p/10777638.html
Copyright © 2020-2023  润新知