CF1341 D. Nastya and Scoreboard

Question

一個n個數碼位的分數板,每一個數碼位都是一個七段數碼管,現在給出每個數碼位的顯示情況,問再點亮k段數碼管的話能顯示的最大的數是多少,如果不能構成一串數字,就輸出-1.

Solution

  1. 貪心+DFS+剪枝
    我們要構造的數最大,那就是高位儘可能大。直接爆搜TLE,考慮優化加入數組v[i][j]v[i][j]表示到第ii個點,還剩jj次操作的時候是否能找到可行解,若爲true代表找不到可行解。
    O(n107)=O(140000)O(n*10*7)=O(140000)一個點搜一次大概這個複雜度吧,可能常數有點大。
    跑了一下172ms。
    還可以進一步優化:
    預處理搜到mi[i]mi[i]表示搜到第ii個點之後所需要的最小值爲多少,ma[i]ma[i]表示搜到第jj個點之後所需要的最大值爲多少,若剩餘操作次數超出範圍直接返回。

Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF  = 0x3f3f3f3f;
const ll  mod  = 1e9 + 7;
const ll  maxn = 1e6 + 5;
const int N = 2000 + 5;

string s[N];
string num[10]={"1110111", "0010010", "1011101", "1011011", "0111010", "1101011", "1101111", "1010010", "1111111", "1111011"};
bool flag=false,v[N][N];
int cnt=0;
int ans[N];
ll n,k;

inline bool check(int x,int y,int t){
	cnt=0;
	for(int i=0;i<7;i++){
		if(num[y][i]=='1'&&s[x][i]=='0') cnt++;
		else if(num[y][i]=='0'&&s[x][i]=='1') return false;
	}
	return cnt<=t?true:false;
}

void dfs(int x,int t){
	if(flag || t<0 || v[x][t]) return;
	if(x==n+1){
		if(t==0){
			flag=true;
			for(int i=1;i<=n;i++) cout<<ans[i];
		}
		return;
	}
	for(int i=9;i>=0;i--){
		if(!check(x,i,t)) continue;
		ans[x]=i;
		dfs(x+1,t-cnt);
	}
	if(!flag) v[x][t]=true;
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>s[i];
	}
	dfs(1,k);
	if(!flag) cout<<-1;
	return 0;
}

DFS+預處理優化(~爲什麼別人跑下來31ms我跑下來155ms因爲我代碼寫的太辣雞了~

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF  = 0x3f3f3f3f;
const ll  mod  = 1e9 + 7;
const ll  maxn = 1e6 + 5;
const int N = 2000 + 5;

string s[N];
string num[10]={"1110111", "0010010", "1011101", "1011011", "0111010", "1101011", "1101111", "1010010", "1111111", "1111011"};
bool flag=false,v[N][N];
int cnt=0;
int ans[N];
ll n,k;
int mi[N],ma[N];

inline bool check(int x,int y,int t){
	cnt=0;
	for(int i=0;i<7;i++){
		if(num[y][i]=='1'&&s[x][i]=='0') cnt++;
		else if(num[y][i]=='0'&&s[x][i]=='1') return false;
	}
	return cnt<=t?true:false;
}

inline void dfs(int x,int t){
	if(t>ma[x] || t<mi[x]) return;
	if(flag || t<0 || v[x][t]) return;
	if(x==n+1){
		if(t==0){
			flag=true;
			for(int i=1;i<=n;i++) cout<<ans[i];
		}
		return;
	}
	for(int i=9;i>=0;i--){
		if(!check(x,i,t)) continue;
		ans[x]=i;
		dfs(x+1,t-cnt);
	}
	if(!flag) v[x][t]=true;
}

void init(){
	for(int i=1;i<=n;i++){
		for(int j=9;j>=0;j--){
			if(!check(i,j,INF)) continue;
			ma[i]=max(ma[i],cnt);
			mi[i]=min(mi[i],cnt);
		}
	}
	for(int i=n;i>=1;i--){
		ma[i]+=ma[i+1];
		mi[i]+=mi[i+1];
	}
}

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		cin>>s[i];
	}
	init();
	dfs(1,k);
	if(!flag) cout<<-1;
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章