• [2019南昌邀请赛网络赛D][dp]


    https://nanti.jisuanke.com/t/38223

    Xiao Ming recently indulges in match stick game and he thinks he is good at it. His friend Xiao Jun decides to test him. Xiao Jun gives him an expression of length , made by match sticks and asks him to calculate the maximum value of the expression by moving any match sticks (but he can’t discard any of them). The expression is made up of some numbers, plus signs and minus signs represented as A_1 op_1 A_2 op_2 A_3 op_3 cdots A_{m - 1} op_{m - 1} A_mA1 op1 A2 op2 A3 op3 Am1 opm1 Ammm must be count by himself, A_k(1 le k le m)Ak(1km) is an integer without leading zeros and less than 10^9109 , op_k (1 le k le m)opk(1km) is a plus sign or a minus sign. At the same time, there are some requirements of the new expression:

    1. The new expression should also be made up of mm numbers and m - 1m1 operators.
    2. The number of digits per number should keep consistent with the original.
    3. There couldn’t be any leading zeros per number.

    Input

    The first line consists of a single integer TTdenoting the number of test cases.

    There’re two lines in each test case.

    The first line contains an integer nn.

    A string of length nn follows in the next line, denoting the expression given.

    The expression is guaranteed to be valid.

    Output

    For each test case, print a single integer denoting the maximum result of the expression.

    Constraints

    1 le n le 1001n100

    Note

    Expression with the maximum result for the second sample is 7 - 171 .

    Expression with the maximum result for the second sample is 7 + 7 + 97+7+9.

    样例输入

    3
    3
    1-1
    3
    1+1
    5
    1+2+3

    样例输出

    0
    6
    23
    题意:给出每个数字和加号减号需要的火柴数,然后给出t组多项式,求不改变多项式项数以及每项数字位数的前提下得到的多项式的最大值
    题解:由于不存在括号而且加法和减法是同级运算,所以这个求解过程满足dp的子问题性质,可以使用dp解决,由于项数以及位数不能变,所以先dp出i个火柴能拼出的j位最大值和最小值,然后dp枚举每一项的前面的符号是+还是-,是加法就使用i火柴能拼出j位数字的最大值更新dp数组,否则就使用最小值更新
     1 #include<iostream>
     2 #include<vector>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<queue>
     6 #include<map>
     7 using namespace std;
     8 char ch[105];
     9 map<char,int>mp;
    10 typedef long long ll;
    11 int q[105];
    12 ll dp[105][705],dp2[705][15],dp3[705][15];
    13 vector<int>g[11];
    14 int main(){
    15     int t;
    16     scanf("%d",&t);
    17     g[6].push_back(0);
    18     mp['0']=6;
    19     g[2].push_back(1);
    20     mp['1']=2;
    21     g[5].push_back(2);
    22     mp['2']=5;
    23     g[5].push_back(3);
    24     mp['3']=5;
    25     g[4].push_back(4);
    26     mp['4']=4;
    27     g[5].push_back(5);
    28     mp['5']=5;
    29     g[6].push_back(6);
    30     mp['6']=6;
    31     g[3].push_back(7);
    32     mp['7']=3;
    33     g[7].push_back(8);
    34     mp['8']=7;
    35     g[6].push_back(9);
    36     mp['9']=6;
    37     mp['+']=2;
    38     mp['-']=1;
    39     memset(dp2,-1,sizeof(dp2));
    40     memset(dp3,-1,sizeof(dp3));
    41     dp2[0][0]=0;
    42     for(int i=1;i<=700;i++){
    43         for(int j=2;j<=7;j++){
    44             for(int k=1;k<15;k++){
    45             if(dp2[i-j][k-1]!=-1&&i>=j)dp2[i][k]=max(dp2[i-j][k-1]*10+g[j][g[j].size()-1],dp2[i][k]);
    46            // if(dp2[i-j]!=-1&&dp2[i][k]==-1&&i>=j)dp2[i][k]=dp2[i-j][k-1]*10+g[j][g[j].size()-1];
    47             }
    48         }
    49     }
    50     dp3[0][0]=0;
    51     for(int i=1;i<=700;i++){
    52         for(int j=2;j<=7;j++){
    53             for(int k=1;k<15;k++){
    54                 if(dp3[i-j][k-1]!=-1&&i>=j)dp3[i][k]=min(dp3[i-j][k-1]*10+g[j][0],dp3[i][k]);
    55                 if(dp3[i-j][k-1]!=-1&&dp3[i][k]==-1&&i>=j)dp3[i][k]=dp3[i-j][k-1]*10+g[j][0];
    56             }
    57         }
    58     }
    59     //for(int i=1;i<=12;i++)cout<<dp2[i]<<endl;
    60     while(t--){
    61         int n;
    62         scanf("%d",&n);
    63         scanf("%s",ch);
    64         int tot=0;
    65         ll sum=0;
    66         int f=0;
    67         for(int i=0;i<n;i++){
    68             if(ch[i]=='+'||ch[i]=='-'){tot++;q[tot]=i-f;f=i+1;}
    69             sum+=mp[ch[i]];
    70         }
    71         q[++tot]=n-f;
    72         memset(dp,-1,sizeof(dp));
    73         dp[0][0]=0;
    74        // cout<<sum<<endl;
    75         for(int i=1;i<=tot;i++){
    76             for(int j=0;j<=sum;j++){
    77                 for(int k=1;k<=100;k++){
    78                     //cout<<dp2[k][q[i]]<<endl;
    79                     if(i>1&&j-k-2>=0&&dp[i-1][j-k-2]!=-1&&dp2[k][q[i]]!=-1)dp[i][j]=max(dp[i-1][j-k-2]+dp2[k][q[i]],dp[i][j]);
    80                     if(i==1&&j-k>=0&&dp[i-1][j-k]!=-1&&dp2[k][q[i]]!=-1)dp[i][j]=max(dp[i-1][j-k]+dp2[k][q[i]],dp[i][j]);
    81                     if(j-k-1>=0&&dp[i-1][j-k-1]!=-1&&dp3[k][q[i]]!=-1)dp[i][j]=max(dp[i-1][j-k-1]-dp3[k][q[i]],dp[i][j]);
    82                     if(dp[i][j]==-1){
    83                         if(i>1&&j-k-2>=0&&dp[i-1][j-k-2]!=-1&&dp2[k][q[i]]!=-1){
    84                             dp[i][j]=dp[i-1][j-k-2]+dp2[k][q[i]];
    85                         }
    86                         if(i==1&&j-k>=0&&dp[i-1][j-k]!=-1&&dp2[k][q[i]]!=-1){
    87                             dp[i][j]=dp[i-1][j-k]+dp2[k][q[i]];
    88                         }
    89                         if(j-k-1>=0&&dp[i-1][j-k-1]!=-1&&dp3[k][q[i]]!=-1){
    90                             dp[i][j]=dp[i-1][j-k-1]-dp3[k][q[i]];
    91                         }
    92                     }
    93                 }
    94             }
    95         }
    96         printf("%lld
    ",dp[tot][sum]);
    97     }
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    VSFTPD无法上传的解决方法
    linux下vsftpd的安装与配置说明
    长轮询
    采用handle消息机制实现轮播效果
    开启AsyncTask从网络加载图片
    使用异步httpclient框架做get,post提交数据
    使用post方式提交数据
    使用get方式提交数据
    json,xml,Html解析
    常用的有关文件上传下载的框架和图片加载框架
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/10895909.html
Copyright © 2020-2023  润新知