【SPOJ】NPC2016C - Strange Waca

Waca loves maths,.. a lot. He always think that 1 is an unique number. After playing in hours, Waca suddenly realize that every integer can be represented by digit '1', plus operator and minus operator. For example, 1534 can be represented as 1111 + 1 + 111 + 111 - 11 - 11 + 111 + 111. In that case, there are total 7 operators (plus and minus).

Now, Waca wants to know, what is the minimum number of operators needed to achieve X

Input

First row is an integer T, the number of test cases.
Next T rows will each contain an integer, X, the number given to Waca

Output

For each test cases, print an integer, the minimum number of operators needed to achieve X.

[预设] cf[i] = 11...11 共i+1个1, "x的答案"指achieve x所需的最少运算符数量, "a到b的花费"指achieve |a-b|所需的最少运算符数量

[引理1] 最优解的算式中不可能同时出现"+cf[i]","-cf[i]"

[引理2] 对于任意的正整数b,a的答案≤b的答案+a到b的花费,且存在一个正整数c满足a的答案=c的答案+a到c的花费

[引理3] 对于任意的正整数a,假设cf[i]≤a≤cf[i+1],如果a的答案不使用cf[j](j>i),那么a的答案要么正好有a/cf[i]个cf[i],要么正好有a/cf[i]+1个cf[i]

引理1和引理2都非常显然,现在我们来证明引理3.

考虑正整数a,cf[i]≤a≤cf[i+1],假设我们使用了正好k个cf[i]。如果k<\frac{a}{cf[i]},在a的最优分解算式 a=k*cf[i]+x_{i-1}*cf[i-1]+...中,两边减去k*cf[i],得到 a-k*cf[i]=x_{i-1}*cf[i-1]+... 此时a-k*cf[i]>cf[i],也就是说,在右边我们要使x_{i-1}\geq 10来满足等式,这显然不是最优的方法,因为cf[i] - 1 = cf[i-1]*10。对于k>\frac{a}{cf[i]}+1,我们可以类似的得到相同的结论。那么我们就不那么严谨地证明了引理3.

现在我们想到了一种方法:如果不考虑高位的cf[i],对于当前的每一位我们都最多有两种填法,这样,我们得到了一种O(X^{log_{10}2})的做法,符合数据范围的要求。

代码如下:

#include
using namespace std;
long long cf[14]={1ll,11ll,111ll,1111ll,11111ll,111111ll,1111111ll,11111111ll,111111111ll,1111111111ll,11111111111ll,111111111111ll,1111111111111ll};
int dfs(int p, long long a){
    if(a == 0) return 0;
    if(p < 0) return 10086;
    int bes = 10086;
    bes = min(1ll * bes, dfs(p - 1, a - a/cf[p] * cf[p]) + a/cf[p]);
    bes = min(1ll * bes, dfs(p - 1, (a/cf[p] + 1) * cf[p] - a) + a/cf[p] + 1);
    return bes;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        long long a;
        cin>>a;
        cout << dfs(12,a) - 1 <

 

你可能感兴趣的:(spoj,搜索,算法)