HDU - 2929 Bigger is Better

来源:互联网 发布:经验模态分解 python 编辑:程序博客网 时间:2024/06/04 18:26

题意:你的任务是用不超过n根火柴摆一个尽量大的,能被m整除的正整数,无解时输出-1


思路:先预处理出用不超过n根火柴能摆成的最大数有几位,那么只有当这个数是m的倍数,它的位数越大才有用,那么用一维记录余数,所以dp[i][j]表示用i根组成的数余数是j的最大位数是多少,接下来的就是打印各个位上的数了,试想一下满足的条件,

dp[i][j]+1==dp[newi][newj]满足的话,那么如果dp[newi][newj]存在的话,那么新增的K就是下一位,用next[i][j]表示当前状态的下一个数

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 110;const int MAXM = 3010;const int used[10] = {6,2,5,5,4,5,6,3,7,6};int dp[MAXN][MAXM],next[MAXN][MAXM];int n,m,maxlen;int main(){    int cas = 0;    while (scanf("%d",&n) != EOF && n){        scanf("%d",&m);        memset(dp,-1,sizeof(dp));        dp[0][0] = 0,maxlen = 0;        for (int i = 0; i < n; i++)            for (int j = 0; j < m; j++)                if (dp[i][j] >= 0)                    for (int k = 9; k >= 0; k--)                        if (i + used[k] <= n){                            int newi = i+used[k],newj = (j*10+k)%m;                            if (dp[i][j] + 1 > dp[newi][newj]){                                dp[newi][newj] = dp[i][j] + 1;                                if (dp[newi][newj] > maxlen && newj == 0)                                    maxlen = dp[newi][newj];                            }                        }        memset(next,-1,sizeof(next));        for (int i = n; i >= 0; i--)            for (int j = 0; j < m; j++)                if (dp[i][j] >= 0){                    if (dp[i][j] == maxlen && j == 0){                        next[i][j] = 10;                        continue;                    }                    for (int k = 9; k >= 0; k--){                        if (i + used[k] <= n){                            int newi = i + used[k];                            int newj = (j*10+k)%m;                            if (dp[newi][newj] == dp[i][j] + 1 && next[newi][newj] >= 0){                                next[i][j] = k;                                break;                            }                        }                    }                }        printf("Case %d: ",++cas);        int i,j,u,v;        if (maxlen > 0){            i = 0,j = 0;            while (next[i][j] != 10){                u = i + used[next[i][j]];                v = (j*10+next[i][j]) % m;                printf("%d",next[i][j]);                i = u,j = v;            }            printf("\n");        }        else if (n >= used[0])                printf("0\n");             else printf("-1\n");    }    return 0;}



0 0