[codeforces792C][dp]
https://codeforc.es/contest/792/problem/C
给一个数字,你可以删除字符串某一个位置的字符,使其满足下列条件:
- 数字没有前导0
- 数字能够被3整除
求经过最少操作次数之后得到的结果。
题解:dp过程记录操作即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define debug(x) cout<<"["<<#x<<"]"<<" is "<<x<<endl; 4 typedef long long ll; 5 int dp[100005][4][2],pre[100005][4][2][2],xx[100005][4][2]; 6 char ch[100005],q[100005]; 7 int main(){ 8 scanf("%s",ch+1); 9 int len=strlen(ch+1); 10 memset(dp,-1,sizeof(dp)); 11 dp[0][0][0]=0; 12 int f=-1; 13 for(int i=1;i<=len;i++){ 14 int x=ch[i]-'0'; 15 if(x){ 16 if((dp[i-1][1][1]!=-1)&&(dp[i][1][1]==-1||(dp[i-1][1][1]+1<dp[i][1][1]))){ 17 dp[i][1][1]=dp[i-1][1][1]+1; 18 pre[i][1][1][0]=1; 19 pre[i][1][1][1]=1; 20 xx[i][1][1]=1; 21 } 22 if((dp[i-1][(1-x+30)%3][1]!=-1)&&(dp[i][1][1]==-1||(dp[i-1][(1-x+30)%3][1]<dp[i][1][1]))){ 23 dp[i][1][1]=dp[i-1][(1-x+30)%3][1]; 24 pre[i][1][1][0]=(1-x+30)%3; 25 pre[i][1][1][1]=1; 26 xx[i][1][1]=0; 27 } 28 if((dp[i-1][(1-x+30)%3][0]!=-1)&&(dp[i][1][1]==-1||(dp[i-1][(1-x+30)%3][0]<dp[i][1][1]))){ 29 dp[i][1][1]=dp[i-1][(1-x+30)%3][0]; 30 pre[i][1][1][0]=(1-x+30)%3; 31 pre[i][1][1][1]=0; 32 xx[i][1][1]=0; 33 } 34 if((dp[i-1][2][1]!=-1)&&(dp[i][2][1]==-1||(dp[i-1][2][1]+1<dp[i][2][1]))){ 35 dp[i][2][1]=dp[i-1][2][1]+1; 36 pre[i][2][1][0]=2; 37 pre[i][2][1][1]=1; 38 xx[i][2][1]=1; 39 } 40 if((dp[i-1][(2-x+30)%3][1]!=-1)&&(dp[i][2][1]==-1||(dp[i-1][(2-x+30)%3][1]<dp[i][2][1]))){ 41 dp[i][2][1]=dp[i-1][(2-x+30)%3][1]; 42 pre[i][2][1][0]=(2-x+30)%3; 43 pre[i][2][1][1]=1; 44 xx[i][2][1]=0; 45 } 46 if((dp[i-1][(2-x+30)%3][0]!=-1)&&(dp[i][2][1]==-1||(dp[i-1][(2-x+30)%3][0]<dp[i][2][1]))){ 47 dp[i][2][1]=dp[i-1][(2-x+30)%3][0]; 48 pre[i][2][1][0]=(2-x+30)%3; 49 pre[i][2][1][1]=0; 50 xx[i][2][1]=0; 51 } 52 if((dp[i-1][0][0]!=-1)&&(dp[i][0][0]==-1||(dp[i-1][0][0]+1<dp[i][0][0]))){ 53 dp[i][0][0]=dp[i-1][0][0]+1; 54 pre[i][0][0][0]=0; 55 pre[i][0][0][1]=0; 56 xx[i][0][0]=1; 57 } 58 if((dp[i-1][0][1]!=-1)&&(dp[i][0][1]==-1||(dp[i-1][0][1]+1<dp[i][0][1]))){ 59 dp[i][0][1]=dp[i-1][0][1]+1; 60 pre[i][0][1][0]=0; 61 pre[i][0][1][1]=1; 62 xx[i][0][1]=1; 63 } 64 if((dp[i-1][(0-x+30)%3][1]!=-1)&&(dp[i][0][1]==-1||(dp[i-1][(0-x+30)%3][1]<dp[i][0][1]))){ 65 dp[i][0][1]=dp[i-1][(0-x+30)%3][1]; 66 pre[i][0][1][0]=(0-x+30)%3; 67 pre[i][0][1][1]=1; 68 xx[i][0][1]=0; 69 } 70 if((dp[i-1][(0-x+30)%3][0]!=-1)&&(dp[i][0][1]==-1||(dp[i-1][(0-x+30)%3][0]<dp[i][0][1]))){ 71 dp[i][0][1]=dp[i-1][(0-x+30)%3][0]; 72 pre[i][0][1][0]=(0-x+30)%3; 73 pre[i][0][1][1]=0; 74 xx[i][0][1]=0; 75 } 76 } 77 else{ 78 f=0; 79 if((dp[i-1][0][0]!=-1)&&(dp[i][0][0]==-1||(dp[i-1][0][0]+1<dp[i][0][0]))){ 80 dp[i][0][0]=dp[i-1][0][0]+1; 81 pre[i][0][0][0]=0; 82 pre[i][0][0][1]=0; 83 xx[i][0][0]=1; 84 } 85 if((dp[i-1][0][1]!=-1)&&(dp[i][0][1]==-1||(dp[i-1][0][1]<dp[i][0][1]))){ 86 dp[i][0][1]=dp[i-1][0][1]; 87 pre[i][0][1][0]=0; 88 pre[i][0][1][1]=1; 89 xx[i][0][1]=0; 90 } 91 if((dp[i-1][1][1]!=-1)&&(dp[i][1][1]==-1||(dp[i-1][1][1]<dp[i][1][1]))){ 92 dp[i][1][1]=dp[i-1][1][1]; 93 pre[i][1][1][0]=1; 94 pre[i][1][1][1]=1; 95 xx[i][1][1]=0; 96 } 97 if((dp[i-1][2][1]!=-1)&&(dp[i][2][1]==-1||(dp[i-1][2][1]<dp[i][2][1]))){ 98 dp[i][2][1]=dp[i-1][2][1]; 99 pre[i][2][1][0]=2; 100 pre[i][2][1][1]=1; 101 xx[i][2][1]=0; 102 } 103 } 104 } 105 int tot=0; 106 if(dp[len][0][1]!=-1&&dp[len][0][1]<dp[len][0][0]){ 107 int t1=0; 108 int t2=1; 109 for(int i=len;i>=1;i--){ 110 if(!xx[i][t1][t2]){ 111 q[++tot]=ch[i]; 112 } 113 int tt1=t1; 114 int tt2=t2; 115 t1=pre[i][tt1][tt2][0]; 116 t2=pre[i][tt1][tt2][1]; 117 } 118 for(int i=tot;i>=1;i--){ 119 printf("%c",q[i]); 120 } 121 printf("\n"); 122 } 123 else{ 124 printf("%d\n",f); 125 } 126 return 0; 127 }