UVa:12105 Bigger is Better

这个题可能有非大数做法,但是我想了好久没想到什么太好的思路,所以用了大数。所以时间很慢,跑了1.4s。

dp【i】【j】表示用i根火柴得到模m余j的最大数字。这样进行转移即可。过程尽量简单,因为时间复杂度比较高,一开始想用vector保存char结果超时了。

注意答案为0的情况。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define MOD 20071027
#define MAXN 1000005
using namespace std;
typedef char BigNum[60];
int v[10] = {6,2,5,5,4,5,6,3,7,6};
BigNum dp[110][3005];
int BigCompare(char *a,char *b)
{
    int la=strlen(a),lb=strlen(b);
    if(la>lb) return 1;
    else if(la<lb) return -1;
    return strcmp(a,b);
}
void solve(char *a,char *b,int u)
{
    int la=strlen(a);
    a[la]='0'+u;
    a[la+1]=0;
    if(BigCompare(a,b)>0) strcpy(b,a);
    a[la]=0;
}
int main()
{
    int n,m,kase=0;
    while(scanf("%d",&n)&&n)
    {
        scanf("%d",&m);
        memset(dp,0,sizeof(dp));
        for(int i=0; i<=n-2; ++i)
            for(int j=0; j<m; ++j)
            {
                if(!(i==0&&j==0)&&strlen(dp[i][j])==0) continue;
                for(int u=0; u<10; ++u)
                    solve(dp[i][j],dp[i+v[u]][(j*10+u)%m],u);
            }
        int u=-1;
        for(int i=1; i<=n; ++i)
            if(strlen(dp[i][0])&&(u==-1||BigCompare(dp[i][0],dp[u][0])>0))
                u=i;
        printf("Case %d: ",++kase);
        if(u!=-1)
        {
            if(strlen(dp[u][0])>1&&dp[u][0][0]=='0')
                puts(dp[u][0]+1);
            else
                puts(dp[u][0]);
        }
        else puts("-1");
    }
    return 0;
}


 

你可能感兴趣的:(动态规划)