CF1340B Nastya and Scoreboard (dp 确定可行方案)

Nastya and Scoreboard

思路:先确定每个位置上变成0~9需要额外点亮多少灯,因为需要用完k个灯,可以有前导零,我们从最后一位开始点亮灯,往前递推可行的方案。dp[当前位置][用了j个灯] = (可行,不可行)。

然后就判断能不能用完k个灯,可以得话从前往后以9~0顺序寻找最大数字。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <functional>
 6 #include <set>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstring>
10 #include <stack>
11  
12 using namespace std;
13  
14 #define ll long long
15 #define pb push_back
16 #define fi first
17 #define se second
18 
19 string digits[10] = { "1110111", "0010010", "1011101", "1011011", "0111010",
20                    "1101011", "1101111", "1010010", "1111111", "1111011" };
21 
22 void solve(){
23     int n, k;
24     cin >> n >> k;
25     vector<string > s(n);
26     for(auto& str : s) cin >> str;
27     vector<vector<int > > dist(n + 1, vector<int>(10 ));
28     for(int i = 0; i < n; ++i){
29         for(int d = 0; d < 10; ++d){
30             for(int j = 0; j < 7; ++j){
31                 char x = s[i][j];
32                 char y = digits[d][j];
33                 if(x == '1' && y == '0'){
34                     dist[i][d] = -1;
35                     break;
36                 }
37                 if(x == '0' && y == '1'){
38                     ++dist[i][d];
39                 }
40             }
41         }
42     }
43 
44     vector<vector<int > > dp(n + 1, vector<int >(k + 1));
45     dp[n][0] = 1;
46     for(int i = n; i > 0; --i){
47         for(int j = 0; j <= k; ++j){
48             if(dp[i][j]){
49                 for(int d = 0; d < 10; ++d){
50                     if(dist[i - 1][d] != -1 && j + dist[i - 1][d] <= k){
51                         dp[i - 1][j + dist[i - 1][d]] = 1;
52                     }
53                 }
54             }
55         }
56     }
57     if(dp[0][k] == 0) cout << "-1" << endl;
58     else{
59         int now = -1;
60         for(int i = 0; i < n; ++i){
61             for(int d = 9; d >= 0; --d){
62                 if(dist[i][d] != -1 && k >= dist[i][d] && dp[i + 1][k - dist[i][d]]){
63                     now = d;
64                     k -= dist[i][d];
65                     break;
66                 }
67             }
68             cout << now;
69         }
70         cout << endl;
71     }
72 }
73  
74 int main(){
75     
76     // freopen("C:\\Users\\admin\\Desktop\\input.txt", "r", stdin);
77     // freopen("C:\\Users\\admin\\Desktop\\output.txt", "w", stdout);
78     ios::sync_with_stdio(false);
79     cin.tie(0);
80     cout.tie(0);
81     solve();
82     
83     return 0;
84 }
85  

 

posted @ 2020-05-05 12:16  SummerMingQAQ  阅读(270)  评论(0编辑  收藏  举报