Luo Gu P5322 (BJOI 2019) DP

### topic Link ###

 

 

analysis:

1, with the vector <int> v [i] to deposit i Castle, s opponent number of soldiers scheduled.

2, set dp [i] [j] represents ago i Castle, the greatest value when the current maximum amount of troops available to j.

3, difficult to think that traverse s opponents, then two for it to send troops to traverse the amount of each opponent's castle. For can then send the update to see if it is sent dp value.

4. Again we consider greedy thinking: if the i-th castle, A player sent a soldier, then at least need to send 2 * a + 1 soldier answers to contribute; furthermore if player B b dispatched a soldier, and b> a, then if we can send 2 * b + 1 soldier, then for a players there can also contribute. So we need to make v [i] to sort, when dp so if large to meet later, less directly so that (more than the number of current players) * i, come to contribute to the current castle.

 

The time complexity of the algorithm is O (nms), it appears to 2 × 10 . 8 , but there will be break dp to prune.

Furthermore, since the transfer equation with only one level i.e. dp [i - 1] [] related, it can be reduced to one dimension.

code show as below:

 

#define IO freopen("test.in","r",stdin),freopen("test.out","w",stdout)
#define inf 0x3f3f3f3f
#define lson root<<1
#define rson root<<1|1
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
int s,n,m;
int a[108],dp[20008];
vector<int> v[108];
int main()
{
    //IO;
    scanf("%d%d%d",&s,&n,&m);
    for(int i=1;i<=n;i++) a[i]=inf;
    int A;
    for(int i=1;i<=s;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&A);
            v[j].push_back(A);
            a[j]=min(a[j],A);
        }
    }
    for(int i=1;i<=n;i++) sort(v[i].begin(),v[i].end());
    for(int i=1;i<=n;i++){
        for(int j=m;j>a[i]*2;j--){
            for(int k=0;k<v[i].size();k++){
                if(j<=v[i][k]*2) break;
                dp[j]=max(dp[j],dp[j-(v[i][k]*2+1)]+(k+1)*i);
            }
        }
    }
    printf("%d\n",dp[m] );
}

 

Guess you like

Origin www.cnblogs.com/Absofuckinglutely/p/11588288.html