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
*/

浙公网安备 33010602011771号