[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\n",dp[tot][sum]);
97     }
98     return 0;
99 }
View Code

 

转载于:https://www.cnblogs.com/MekakuCityActor/p/10895909.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值