D. Nastya and Scoreboard
链接:https://codeforces.com/contest/1341/problem/D
题意;给出n个字符串,k个操作。
每个字符串表示一个残缺的数字,我们可以用若干个操作把这个数字补成(0~9)中的其中任意一个数字
我们需要恰好补齐k个操作;
假如不能补齐,就输出-1
假如能补齐,就输出能够构成的最大的那个数
思路:这道题很容易想到用dfs的方法来做
在dfs之前,我们需要预处理一下,每一个字符串变成(0~9)的需要的操作数;
然后dfs的时候,我们自然是从最优情况开始枚举
最优情况就是从大到小(因为要我们求出最大值)
然后逐一枚举即可;
但是,这样子dfs会超时。
可以发现,dfs的过程中,有一些情况下是会重复的,我们把这些情况记录下来,下次再遇到这种情况,就直接得出答案退出即可
这种情况跟数位DP类似(在本代码中记忆化为dp数组)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=2e3+10; 5 int d[20][20]; 6 char mp[maxn][20]; 7 int dp[maxn][maxn]; 8 int cnt[maxn][maxn]; 9 vector<int>num; 10 int solve(int n,int now,int ls,int k) 11 { 12 if(ls>k) return 0; //假如目前操作数已经大于k 就退出 13 if(n==now-1&&k==ls) return 1; //满足情况,赋值为1,退出 14 else if(n==now-1&&k!=ls) return 0; //不满足,赋值为0,退出 15 if(dp[now][ls]!=-1) return dp[now][ls]; //记忆化 16 for(int i=9;i>=0;i--){ //从大到小枚举 17 if(cnt[now][i]<0) continue; 18 if(solve(n,now+1,ls+cnt[now][i],k)){ 19 num.push_back(i); 20 dp[now][ls]=1; 21 return 1; 22 } 23 } 24 dp[now][ls]=0; 25 return 0; 26 } 27 int main() 28 { 29 d[0][1]=1,d[0][2]=1,d[0][3]=1,d[0][5]=1,d[0][6]=1,d[0][7]=1; 30 d[1][3]=1,d[1][6]=1; 31 d[2][1]=1,d[2][3]=1,d[2][4]=1,d[2][5]=1,d[2][7]=1; 32 d[3][1]=1,d[3][3]=1,d[3][4]=1,d[3][6]=1,d[3][7]=1; 33 d[4][3]=1,d[4][4]=1,d[4][6]=1,d[4][2]=1; 34 d[5][1]=1,d[5][2]=1,d[5][4]=1,d[5][6]=1,d[5][7]=1; 35 d[6][1]=1,d[6][2]=1,d[6][4]=1,d[6][5]=1,d[6][6]=1,d[6][7]=1; 36 d[7][1]=1,d[7][3]=1,d[7][6]=1; 37 d[8][1]=1,d[8][2]=1,d[8][3]=1,d[8][4]=1,d[8][5]=1,d[8][6]=1,d[8][7]=1; 38 d[9][1]=1,d[9][2]=1,d[9][3]=1,d[9][4]=1,d[9][6]=1,d[9][7]=1; 39 int n,k; 40 scanf("%d%d",&n,&k); 41 for(int i=1;i<=n;i++){ 42 scanf("%s",mp[i]+1); 43 } 44 //记忆化赋初值 45 for(int i=0;i<=2000;i++) 46 for(int j=0;j<=2000;j++){ 47 dp[i][j]=-1; 48 } 49 //预处理过程 50 for(int i=1;i<=n;i++){ 51 for(int j=0;j<=9;j++){ 52 for(int z=1;z<=7;z++){ 53 if(d[j][z]==1&&mp[i][z]=='0'){ 54 cnt[i][j]++; 55 } 56 else if(d[j][z]==0&&mp[i][z]=='1'){ 57 cnt[i][j]=-inf; 58 } 59 } 60 } 61 } 62 solve(n,1,0,k); 63 if(!num.size()) printf("-1\n"); 64 else{ 65 for(int i=num.size()-1;i>=0;i--){ 66 printf("%d",num[i]); 67 } 68 printf("\n"); 69 } 70 return 0; 71 }