[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 ⋯Am−1 opm−1 Am. mm must be count by himself, A_k(1 \le k \le m)Ak(1≤k≤m) is an integer without leading zeros and less than 10^9109 , op_k (1 \le k \le m)opk(1≤k≤m) is a plus sign or a minus sign. At the same time, there are some requirements of the new expression:
- The new expression should also be made up of mm numbers and m - 1m−1 operators.
- The number of digits per number should keep consistent with the original.
- 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 1001≤n≤100
Note
Expression with the maximum result for the second sample is 7 - 17−1 .
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 }