zoukankan      html  css  js  c++  java
  • POJ 1426 Find The Multiple(DP + 抽象01背包)

    题意:

    给定一个数 n(n <= 200), 输出一个由 01 组成的十进制数(长度不超过100),并且这个数是 n 的倍数。

    思路:

    1. 由于题目限定了 n 的范围以及输出的范围,普通的 DFS/BFS 是能够解题的,只不过时间复杂度较高,达到 70ms+;

    2. 抓住由“01 组成的十进制数”这个特性,可以把问题抽象成由:1,10,100,1000,10000……其中任意多个组成的符合题意的数;

    3. dp[i][j] 表示前 i 个数,能否表示成余 j 的形式,能则记录最小的一个;不能则为 0。dp[i][j] = min(dp[i-1][j], dp[i-1][r] + 10i);

    4. 特别注意的是,当 j = 0 时,要特殊处理下,因为即使 dp[i-1][0] = 0, 去求 dp[i][r] 仍然是正确且必要的。最终时间为 0ms;

    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    __int64 dp[110][210];
    
    __int64 solve(int n) {
        int rem = 1;
        __int64 exp = 1;
    
        memset(dp[0], 0, sizeof(dp[1]));
        dp[0][1] = 1;
    
        for (int i = 1; i <= 100; i++) {
            exp *= 10;
            rem = (rem * 10) % n;
            for (int j = 0; j < n; j++) {
                dp[i][j] = dp[i-1][j];
            }
            for (int j = 0; j < n; j++) {
                if (dp[i-1][j] || j == 0) {
                    int r0 = (j + rem) % n;
                    if (dp[i][r0] == 0)
                        dp[i][r0] = exp + dp[i-1][j];
                    if (r0 == 0) 
                        return dp[i][r0];
                }
            }
        }
        return 0;
    }
    
    int main() {
        int n;
        while (scanf("%d", &n) && n) {
            if (n == 1) 
                printf("1\n");
            else
                printf("%I64d\n", solve(n));
        }
        return 0;
    }
  • 相关阅读:
    maven工程的目录结构
    集合的区别
    名词解析
    1.(字符串)-判断字符串是否是子集字符串
    1.(字符串)-判断两字符串是否相等
    python max函数技巧
    1.(字符串)-子字符串位置查找
    numpy线性代数np.linalg
    Python图像库PIL 使用
    pyhthon-chr
  • 原文地址:https://www.cnblogs.com/kedebug/p/2969831.html
Copyright © 2011-2022 走看看