JZOJ3404 [NOIP2013 Simulation] card game (2019.08.04 [NOIP improve group] Model Group B T2)

Portal

Card game (Standard IO) 

Time Limits: 1000 ms  Memory Limits: 524288 KB  Detailed Limits  

Time to Submit: 01:59:17

Description

Small X in order to show their superb skills of the game, one day happily find a small Y playing a card game. Each card has a type (attack or defense) and two power value information.

Small cards Y n-card, the small card X has the m. X known small cards that are all type of attack.

Each round of the game by the small X operating, first select a not used the card from his hand X. If you do not have the small Y card, the damage to the power of the value of X, otherwise little X to Y is selected from small hand a card Y. If Y is attacking (power only when the value of X is not less than the value of Y power optional), disappeared after the end of the current round of Y, Y small the damage is the difference between the power value of the power value of X and Y; if Y defensive type (power only when the value of X is greater than Y force value selectable), disappeared after the end of the current round of Y, Y does not hurt small.

X may end his small operation (cards do not have to run out) at any time. Smart hope you help him operate so that the total damage small Y at risk.

Input

First line of input contains two integers n and m.

The next n lines contains a string and an integer, respectively, of a small Y type of card ( "ATK" represents the attack, "DEF" represents defensive) and strength values.

Next m lines contains an integer that represents the power of a card value of X is small.

Output

Output line contains an integer representing the maximum total damage suffered by small Y.

Sample Input

Input 1:

2 3

ATK 2000

DEF 1700

2500

2500

2500

Input 2:

3 4

ATK 10

ATK 100

ATK 1000

1

11

101

1001

Sample Output

Output 1:

3000

Sample Description [1]

The first round, small X to choose their first cards and small Y's second card, small Y's second card disappear.

The second round, small X to choose their second card and a small Y of the first card, the small card Y of the first to disappear, while being 500 damage.

The third round, small X to choose their third card, then the hands of small Y has no cards, by 2500 damage.

X small end of the game, the small Y 3000 were subject to damage.

Output 2:

992

Sample Description [2]

The first round, small X to choose their third cards and small Y of the first card, the small card Y of the first to disappear, while being 91 points of damage.

The second round, small X to choose their own cards and fourth small Y's second card, the small card Y's second disappearance, at the same time by 901 points of damage.

X small end of the game, by a total of 992 small Y damage.

 

Data Constraint

Half of all sizes are small data satisfy Y only attack cards.

For 30% of the data, 1≤ n, m ≤ 6.

For 60% of the data, 1≤ n, m ≤10 ^ 3 .

To 100% of the data, 1≤ n, m ≤10 ^ 5 , the power values are non-negative integers not more than 10 ^ 6.

 

 A violent search (30)

This problem can currently guarantee the right looks like the search, but it will TLE's.

#include<bits/stdc++.h>
using namespace std;
inline int poread()
{
    char c = 0;
    int res = 0;
    while(!isdigit(c = getchar()));
    do
    {
        res = res * 10 + c - 48;
    }
    while(isdigit(c = getchar()));
    return res;
}
const int MAXN = 1e5 + 5;
int n,m;
struct node
{
    bool isstack;
    int force;
}Y[MAXN];
int X[MAXN];
bool v_Y[MAXN],v_X[MAXN];
int ans;
void dfs(int now,int cnt)
{
    ans = max(ans,now);
//    cerr<<cnt<<":"<<now<<" "<<x<<" "<<y<<endl;
//    for(register int i = 1; i <= n; ++i)
//        cerr<<v_Y[i];
//    cerr<<endl;
//    for(register int i = 1; i <= m; ++i)
//        cerr<<v_X[i];
//    cerr<<endl;
    if(cnt > m )
    {
        return;
    }
    int sum = now;
    if(cnt >= n)
    {
        for(register int j = 1; j <= m; ++j)
        {
            if(!v_X[j])
            {
                
                sum = now;
                v_X[j] = true;
                sum += X[j];
                dfs(sum, cnt + 1);
                v_X[j] = false;
            }
            
        }
    }
    else
    {
        for(register int i = 1; i <= n; ++i) 
        {
            if(!v_Y[i])
            {
                for(register int j = 1; j <= m; ++j) 
                {
                    
                    if(!v_X[j])
                    {
                        sum = now;
                        
                        if(Y[i].isstack)
                        {
                            if(X[j] < Y[i].force)
                                continue;
                            sum += (X[j] - Y[i].force);
                        }
                        else
                        {
                            if(X[j] <= Y[i].force)
                                continue;
                        }
                        v_Y[i] = true, v_X[j] = true;
                        dfs(sum,cnt + 1);
                        v_Y[i] = false,    v_X[j] = false;
                    }
                }
            }    
        }    
    }        
}
int main()
{
#ifdef lky233
    freopen("testdata.in","r",stdin);
    freopen("testdata.out","w",stdout);
#endif
    n = poread();
    m = poread();
    for(register int i = 1; i <= n; ++i)
    {
        char s[10];
        scanf("%s",s);
        Y[i].force = poread();
        Y[i].isstack = (s[0] == 'A');
    }
    for(register int i = 1; i <= m; ++i)
    {
        X[i] = poread();
    }
    dfs(0,0);
    cout<<ans<<endl;
}

Second, the pan of greed

This greedy strategy is that, first of all for that matter, there are two strategies:

  1, to attack the other's attack cards to get the end of the game after the score.

    The master said: For this strategy, we will be descending order x, y from small to large, it has been attacked until the end.

    For sample 2, the policy can be, and was originally A of this problem.

    Hack:  

    March 2
    Computer 599
    Computer 1000
    1200
    600
    450

 

    Obviously if you use the above strategy, ans = 601, but 1200> 1000,600-> 599,450-> face, you will get 651 points.

  2, take all the opponent's cards light, and with their own cards to play each other face direct attack.

    For this strategy, it should be consumed with minimal lift off the shield to answer no contribution after use policy 1 Attack cards, and finally make up their faces.

    For data pan, using the y and descending row again calculated over max embodiment taken out. (Data-oriented programming Gong)

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int poread()
{
    char c = 0;
    int res = 0;
    while(!isdigit(c = getchar()));
    do
    {
        res = res * 10 + c - 48;
    }
    while(isdigit(c = getchar()));
    return res;
}
const int MAXN = 1e5 + 7;
int n,m;
int ans_1,ans_2,ans_3;
struct node
{
    int x;
    bool isstack;
    void in()
    {
        char s[10];
        scanf("%s",s);
        isstack = (s[0] == 'A');
        x = poread();
    }
}datax[MAXN],datay[MAXN],x[MAXN],y[MAXN],tmpdata[MAXN];
bool cmp1(node a,node b)//从小到大 
{
    return a.x < b.x;
}
bool cmp2(node a,node b)//从大到小
{
    return a.x > b.x;
}
void tan_1()//只打掉Attack 
{
    int tmpans_1 = 0,tmpans_2 = 0;
    int tmpm = 0,tmpn = 0;
    memset(x,0,sizeof(x));
    memset(y,0,sizeof(y));
    memcpy(x,datax,sizeof(datax));
    for(register int i = 1;i <= n; ++i)
    {
        if(datay[i].isstack)
            y[++tmpn] = datay[i];
    }
    sort(y+1,y+tmpn+1,cmp1);
    sort(x+1,x+m+1,cmp2);
    int nn = min(tmpn,m);
    for(register int i = 1; i <= nn; ++i)
    {
        if(x[i].x < y[i].x)
            break;
        tmpans_1 += x[i].x - y[i].x;
    }
    sort(y+1,y+tmpn+1,cmp2);
    for(register int i = 1; i <= nn; ++i)
    {
        if(x[i].x < y[i].x)
            break;
        tmpans_2 += x[i].x - y[i].x;
    }
    ans_1 = max(tmpans_1,tmpans_2);
}
bool v[MAXN];
void tan_2()
{
    if(n > m)
    {
        ans_2 = 0;
        return;
    }
    int tmpans_1 = 0,tmpans_2 = 0;
    memset(x,0,sizeof(x));
    memset(y,0,sizeof(y));
    for(register int i = 1; i <= m; ++i)
    {
        tmpdata[i] = datax[i];
    }
    int tmpm = 0,tmpn = 0;
    for(register int i = 1; i <= n; ++i)
    {
        if(!datay[i].isstack)
            y[++tmpn] = datay[i];
    }
    //双指针,破盾 
    sort(tmpdata+1,tmpdata+m+1,cmp1);
    sort(y+1,y+tmpn+1,cmp1);
    int point1 = 1,point2 = 1,tmp_cnt = 0;

    while(point1 <= m && point2 <= tmpn)
    {
//        cerr<<point1<<endl;
        while(tmpdata[point1].x <= y[point2].x)
        {
            if(point1 > m)
                break;
            ++point1;
        }
        if(tmpdata[point1].x >the y-[Point2] .x)
             ++ tmp_cnt, v [Point1] = to true ;
         ++ Point2;
         ++ Point1; 
    } 
//     cerr << 1 << endl;
     // can not break all the shield, this strategy is not feasible. 
    IF (tmp_cnt < TMPn) 
    { 
        ans_3 = 0 ;
         return ; 
    } 
    TMPn = TMPM = 0 ;
     for (Register int I = . 1 ; I <= m; ++ I) 
    { 
        IF (! V [I]) 
            X [ ++ tmpm] = tmpdata[i];    
    }
    memset(y,0,sizeof(y));
    for(register int i = 1; i <= n; ++i)
    {
        if(datay[i].isstack)
            y[++tmpn] = datay[i];
    }
    
    
    sort(y+1,y+tmpn+1,cmp1);
    sort(x+1,x+tmpm+1,cmp2);
    int nn = min(tmpn,tmpm),mm = max(tmpn,tmpm);
    #ifdef lky233
    for(register int i = 1; i <= tmpm; ++i)
        cerr << x[i].x << endl;
    for(register int i = 1; i <= tmpn; ++i)
        cerr << y[i].x << endl;
    #endif
    bool con = 1;
    for(register int i = 1; i <= nn; ++i)
    {
        if(x[i].x < y[i].x)
        {
            con = 0;
            break;
        }
        tmpans_1 += x[i].x - y[i].x;
    }
    if(con)
        for(register int i = nn + 1; i <= mm; ++i)
        {
            tmpans_1 += x[i].x;
        }
    con = 1;
    sort(y+1,y+tmpn+1,cmp2);
    for(register int i = 1; i <= nn; ++i)
    {
        if(x[i].x < y[i].x)
        {
            con = 0;
            break;
        }
        tmpans_2 += x[i].x - y[i].x;
    }
    if(con)
        for(register int i = nn + 1; i <= mm; ++i)
        {
            tmpans_2 += x[i].x;
        }
    ans_2 = max(tmpans_1,tmpans_2);
//    cerr<<tmpans_1<<' '<<tmpans_2<<endl;
    return;
}
signed main()
{
#ifdef lky233
    freopen("testdata.in","r",stdin);
    freopen("testdata.out","w",stdout);
#endif
    n = poread();
    m = poread();
    for(register int i = 1; i <= n; ++i)
        datay[i].in();
    for(register int i = 1; i <= m; ++i)
        datax[i].x = poread();
    tan_1();
    tan_2();
//    cerr<<ans_1<<" "<<ans_2<<endl;
    cout<<max(ans_1,ans_2)<<endl;
    return 0;
}

Redundant code optimization also very much ......

Third, realize that greed is the right and then to supplement

Hack actual data is considered to be the policy 2.

Strategy 2 Fixed: rip each other's shield, after one's own sigma Attack - other sigma Attack;

Strategy 1 Proof: use a smaller number of attacks on each other's number, will reduce the contribution.

Strategy 2: As long as the other party can be broken shield, attack order is already not affect the final answer ......

 

Code Gugu Gu away, dormitory.

Guess you like

Origin www.cnblogs.com/Shiina-Rikka/p/11300035.html