这道题目有人用DFS、有人用DP
我觉得还是最简单的贪心解决也是不错的选择。
Ok,不废话了,这道题目的意思就是
原先存在一个严格递增的Arrary_A,然后Array_A[i] 的每位之和为Array_B[i]
现在给你一个Array_B, 让你在条件:
Array_A[len] Minimize
下求出次数组
(当然我们很容易得出,如果Array_A[len] 不是最小化的,那么答案有无穷多,随意暴力一下都可以)
所以这题没有那么暴力= =
解题思路:
首先求出Array_B[i] 和 Array_B[i - 1]的差 delta
如果delta > 0, 那么对Array_A从右到左依次加上去,易得在数据范围内不会TLE
使得最后的Array_A 为 (Carry)9* // Carry为进位, 9*代表后面跟着n个0,n可为0
实现方法可以看下面的代码。
如果delta < 0,对Array_A 从右开始,低于delta的位数清零
同时把Array_A[i] 加进delta
因为接下来有一个操作,需要对Array_A[i]自加1
以防9 + 1 = 10这样的情形出现,所以需要将Array_A[i]开始连续为9的位都清零
同时把Array_A[i] 加进delta
然后重复delta > 0 的情形的操作
经测试最大的答案在300+位,所以数组可以适当开大一点...
Source code:
//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler #include <bits/stdc++.h> #define Max(a,b) (((a) > (b)) ? (a) : (b)) #define Min(a,b) (((a) < (b)) ? (a) : (b)) #define Abs(x) (((x) > 0) ? (x) : (-(x))) #define MOD 1000000007 #define pi acos(-1.0) using namespace std; typedef long long ll ; typedef unsigned long long ull ; typedef unsigned int uint ; typedef unsigned char uchar ; template<class T> inline void checkmin(T &a,T b){if(a>b) a=b;} template<class T> inline void checkmax(T &a,T b){if(a<b) a=b;} const double eps = 1e-7 ; const int N = 1 ; const int M = 200000 ; const ll P = 10000000097ll ; const int INF = 0x3f3f3f3f ; int b1, b2; int a[1000], len; void output(){ for(int i = len; i >= 1; --i){ printf("%d",a[i]); } puts(""); } void add(int num){ int i = 1; while(num){ if(9 == a[i]){ ++i; } else{ ++a[i]; --num; } } checkmax(len, i); } void add_new(int num){ int i = 1; while(num <= 0){ num += a[i]; a[i++] = 0; } while(9 == a[i]){ num += a[i]; a[i++] = 0; } ++a[i]; --num; checkmax(len, i); add(num); } int main(){ int i, j, t, n, m; while(EOF != scanf("%d",&t)){ memset(a, 0, sizeof(a)); len = 1; scanf("%d",&b1); add(b1); output(); for(i = 1; i < t; ++i){ scanf("%d",&b2); int delta = b2 - b1; b1 = b2; if(delta > 0) add(delta); else add_new(delta); output(); } } }