UVA 12105 Bigger is Better

来源:互联网 发布:手机怎么上电脑版淘宝 编辑:程序博客网 时间:2024/05/20 13:13

题目链接:http://acm.hust.edu.cn/vjudge/problem/42073


题意:每个数字可以由若干个火柴摆成,现在用不超过n根火柴,求摆出来的能整除m的最大数。


思路:dp[i][j]表示用不超过i根火柴摆出来的除m余j的最大数。对于一个已经求出来的dp[i][j],我们可以借助它来更新,枚举最后一位放的数字k,更新dp[i+num(k)][(j*10+k)%m],由于数很大,所以用字符串的形式去存储。


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <iostream>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <sstream>#include <queue>#include <utility>using namespace std;#define rep(i,j,k) for (int i=j;i<=k;i++)#define Rrep(i,j,k) for (int i=j;i>=k;i--)#define Clean(x,y) memset(x,y,sizeof(x))#define LL long long#define ULL unsigned long long#define inf 0x7fffffff#define mod 100000007struct node{    int len;    string x;    bool operator > ( const node &temp )    {        if ( len != temp.len ) return len > temp.len;        return x > temp.x;    }};node dp[110][3002];bool flag[110][3002];int digit[] = { 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 };int n,m;void update( node &a , node &b , bool &c ){    if ( !c )        a = b , c = true;    else        if ( b > a ) a = b;}void init(){    Clean(flag,false);    flag[0][0] = true;    dp[0][0].len = 0;    dp[0][0].x = "";    node temp;    rep(i,0,n)        rep(j,0,m-1)        if ( flag[i][j] )        {            update( dp[i+1][j] , dp[i][j] , flag[i+1][j] );  //更新dp[i+1][j]  给i+1根 只用i根            rep(k,0,9)            {                temp.len = dp[i][j].len + 1;                temp.x = dp[i][j].x + (char)( '0' + k );                update( dp[i+digit[k]][ (j*10+k)%m ] , temp , flag[i+digit[k]][ (j*10+k)%m ] );            }        }}int main(){    int kase = 0;    while( cin>>n>>m )    {        printf("Case %d: ",++kase);        init();        if ( dp[n][0].len != 0 )        cout<<dp[n][0].x<<endl;        else puts("-1");    }    return 0;}



0 0