CF-div2-637-D. Nastya and Scoreboard | dp 욕심 기억화 검색

1836 단어

아이디어 1


ffs 메모리 검색

생각 2


욕심
  • 예처리val[i][j]제i개로 숫자 j포인트를 만드는 비용
  • dp[i][cnt]는 뒤에서 앞으로 i개까지 모두 cnt뿌리에서 숫자를 모을 수 있는지 i개로 숫자 j를 모을 수 있는지를 가정하면 dp[i][뒤에서 앞으로 i개까지의 비용] | dp[i+1][뒤에서 앞으로 i+1개까지의 비용-cost]
  • cost는 고정할 수 있다. 고정되지 않은 것은 전 i개가 모두 얼마를 썼는가이다. 즉, 현재 이번 라운드에서 숫자 j를 모은 비용은 고정된 cost개이고, 고정되지 않은 것은 뒤에서 앞으로 i개까지 모두 비용이다.
    뒤에서 앞으로 i개까지 총 얼마를 썼는지 열거하면 dp[i][i개까지 총 비용] |= dp[i+1][i개까지 총 비용 - i개의cost 비용]

    dp 코드

    #include
    using namespace std;
     
    const int inf = 0x3f3f3f3f;
    const int maxn = 2e3+100;
    const string str[] = {"1110111","0010010","1011101","1011011","0111010","1101011","1101111","1010010","1111111","1111011"};
     
    string s;
     
    int val[maxn][10];
    int dp[maxn][maxn];
    
     
    void init(int pos){
    	for(int i=0;i<=9;i++){
    		bool flag=false;
    		int cnt=0;
    		for(int j=0;j<7;j++){
    			if(str[i][j]!=s[j]){
    				if(s[j]=='1'){
    					flag=true;
    					break;
    				}
    				cnt++;
    			}
    		}
    		if(flag) val[pos][i] = -1;
    		else val[pos][i] = cnt;
    	}
    }
    
     
    int main(){
    	int n,k;
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++){
    		cin>>s;
    		init(i);
    	}
    	dp[n+1][0]=true; //  :  n+1  0  
    	for(int i=n;i>=1;i--){
    		for(int j=0;j<=9;j++){ // i     j 
    			int cost = val[i][j]; // i   cost     j 
    			if(cost == -1) {
    				dp[i][cost] = 0;
    				continue;
    			}
    			for(int t = cost;t<=k;t++){ 
    				dp[i][t] |= dp[i+1][t-cost]; 
    			}
    		}
    	}
    	if(!dp[1][k]) return 0*puts("-1");
    	
    	//       
    	string ans;
    	for(int i=1;i<=n;i++){
    		for(int j=9;j>=0;j--){
    			if(val[i][j]!=-1 && dp[i+1][k-val[i][j]] == 1){
    				k -= val[i][j];
    				ans += to_string(j);
    				break;
    			}
    		}
    	}
    	cout<

    좋은 웹페이지 즐겨찾기