Bigger is Better UVA

来源:互联网 发布:遭遇网络诈骗如何报警 编辑:程序博客网 时间:2024/06/04 17:57

比较简单的一道题目,按照动态规划的思想,dp[i][j]代表i位数模m的结果为j的所使用的最少火柴的个数。注意在找结果的过程当中我们是从高位向低位进行查找的,同时注意我们在最后查找结果的过程当中终止条件是i>0,这是因为位数不可能为0。具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>using namespace std;int n, m;int dp[55][3010];int remain[55];int record[] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 };void dfs(int length, int number){if (length == 0){cout << endl;return;}for (int i = 9; i >= 0; i--){int new_n = (number - ((remain[length-1] * i) % m) + m) % m;if (dp[length - 1][new_n] + record[i] <= n){cout << i;n -= record[i];dfs(length - 1, new_n);return;}}}int main(){int Case = 0;while (cin >> n&&n){cin >> m;cout << "Case " << ++Case << ": ";remain[0] = 1;for (int i = 1; i < 55; i++){remain[i] = (remain[i - 1] * 10) % m;}for (int i = 0; i <= n / 2; i++){for (int j = 0; j < m; j++) dp[i][j] = 1 << 30;}dp[0][0] = 0;for (int i = 0; i < n / 2; i++){for (int j = 0; j < m; j++){if (dp[i][j] != 1 << 30){int d = dp[i][j];for (int num = 0; num <= 9; num++){dp[i + 1][(j * 10 + num) % m] = min(dp[i + 1][(j * 10 + num) % m], d + record[num]);}}}}int result = -1;for (int i = n / 2; i > 0; i--){if (dp[i][0] != 1 << 30 && dp[i][0] <= n){result = i;break;}}if (result == -1){cout << result << endl;}else{dfs(result,0);}}return 0;}

原创粉丝点击