linkkkk
题意:
给出
n
n
n个灯,再点亮恰好
k
k
k节灯管,问能够组成的最大数,允许有前导零。
思路:
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]表示从
i
−
n
i-n
i−n花费
j
j
j根灯管能够在
i
i
i得到的最大数.
代码:
string str[]={"1110111", "0010010", "1011101", "1011011", "0111010", "1101011", "1101111", "1010010", "1111111", "1111011" };
int dp[2100][2100];
string s[2100];
int cul(string s,int id){
int ans=0;
for(int i=0;i<s.size();i++){
if(s[i]=='1'&&str[id][i]=='0') return -1;
else if(s[i]=='0'&&str[id][i]=='1') ans++;
}
return ans;
}
int main(){
int n=read,k=read;
rep(i,1,n){
cin>>s[i];
}
memset(dp,-1,sizeof dp);
//dp[i][j]表示从i~n花费j根灯管能够在第i得到的最大数
for(int i=n;i;i--){
if(i==n){
for(int j=0;j<10;j++){
int tmp=cul(s[i],j);
if(tmp==-1) continue;//无法变成这个数
dp[i][tmp]=max(dp[i][tmp],j);
}
}
else{
for(int j=0;j<10;j++){
int tmp=cul(s[i],j);
if(tmp==-1) continue;
for(int t=tmp;t<=k;t++)
if(dp[i+1][t-tmp]!=-1)
dp[i][t]=max(dp[i][t],j);
}
}
}
if(dp[1][k]==-1) puts("-1");
else{
int now=k;
for(int i=1;i<=n;i++){
cout<<dp[i][now];
now-=cul(s[i],dp[i][now]);
}
}
return 0;
}
/**
**/