UVA12105

思路

首先我们可以得到一个很显然的 DP,我们定义 \(f_{i,j}\) 为现在用了 \(i\) 根值 \(\bmod m=j\) 的最大值,那么我们可以枚举 \(i,j\) 然后枚举第 \(i\) 位选什么即可。

所以可得转移方程为 \(f_{i+num_k,(j\times 10+k)\bmod m}=\max(f_{i,j}\times 10+k,f_{i+num_k,(j\times 10+k)\bmod m})\)

但是我们会发现 \(f_{i,j}\) 会非常大,所以我们就要用字符串 Dp 了。

这里只需要写一下字符串取最大值即可,这里可以先判断长度再直接用 \(a\) 是否大于 \(b\) 即可。

代码

#include <bits/stdc++.h>
using namespace std;
#define rep(i,x,y) for(register int i=x;i<=y;i++)
#define rep1(i,x,y) for(register int i=x;i>=y;--i)
#define in(x) scanf("%d",&x)
#define fire signed
#define il inline
int n,m,idx;
string f[110][3001];
const int num[]={6,2,5,5,4,5,6,3,7,6};
string smax(string x,string y) {
	if(x.size()!=y.size()) return x.size()>y.size()?x:y;
	else return x>y?x:y;
}
fire main() {
	while(cin>>n,n) {
		in(m);
		printf("Case %d: ",++idx);
		rep(i,0,n) rep(j,0,m-1) f[i][j]="";
		for(char a='0';a<='9';a++) {
			f[num[a-'0']][(a-'0')%m]=a;
		}
		rep(i,1,n) {
			rep(j,0,m-1) {
				if(f[i][j].size()==0) continue;
				rep(k,0,9) {
					if(i+num[k]>n) continue;
					string st=f[i][j];
					st+=(k+'0');
					int gett=(j*10%m+k)%m;
					f[i+num[k]][gett]=smax(f[i+num[k]][gett],st);
				}
			}
		}
		string ans;
		rep(i,1,n) ans=smax(ans,f[i][0]);
		if(ans.size()!=0) {
			for(auto x:ans) printf("%c",x);
		}else printf("-1");
		puts("");
	}
	return 0;
}
/*
100 1
*/
posted @ 2024-02-27 18:27  highkj  阅读(9)  评论(0)    收藏  举报