• POJ 1143


    最开始DP思路大方向是对的,但是一直苦于状态不知道怎么表示。

    略览下题解思路,状态压缩,用是经常用,之前也联系过,实战上还是显出生疏了,对这么常用的技巧竟然一时没想起来

    真正写代码的时候也磕磕绊绊debug了很久,一边怕数组越界,一边担心数组开爆,但最后数组还是开小了,RUNTIMEERROR好久

    还是差的很多,继续提升吧

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <stack>
    #include <map>
    #include <set>
    using namespace std;
    
    const int maxn= 25;
    const int maxs= 21;
    
    int a[maxn];
    bool ck[maxn];
    bool dv[(1<<maxs)+5], vis[(1<<maxs)+5];
    int n;
    
    bool DP(int st)
    {
    	if (vis[st]){
    		return dv[st];
    	}
    
    	int lose= 1;
    	for (int i= 0; i< n && lose; ++i){
    		if (!ck[a[i]]){
    			continue;
    		}
    		int t_st= st ^ (1<<a[i]);
    		ck[a[i]]= 0;
    		int drop= 0;
    		drop|= (1<<i);
    		for (int j= i+1; j< n; ++j){
    			if (!ck[a[j]]){
    				continue;
    			}
    			int flag= 1;
    			if (0== a[j]%a[i]){
    				flag= 0;
    			}
    			for (int p= a[j]-a[i]; p> 1 && flag; p-= a[i]){
    				if (!ck[p]){
    					flag= 0;
    				}
    			}
    			if (!flag){
    				t_st^= (1<<a[j]);
    				ck[a[j]]= 0;
    				drop|= (1<<j);
    			}
    		}
    
    		if (!DP(t_st)){
    			lose= 0;
    		}
    		vis[t_st]= 1;
    		for (int k= i; k< n; ++k){
    			if (drop & (1<<k)){
    				ck[a[k]]= 1;
    			}
    		}
    	}
    
    	vis[st]= 1;
    	return dv[st]= lose ? 0 : 1;
    }
    int main(int argc, char const *argv[])
    {
    	int kase= 0;
    	while (~scanf("%d" ,&n) && n){
    		vector<int> ans;
    		memset(ck, 0 ,sizeof(ck));
    		memset(vis, 0, sizeof(vis));
    		int st= 0;
    		for (int i= 0; i< n; ++i){
    			scanf("%d", a+i);
    			ck[a[i]]= 1;
    			st|= (1<<a[i]);
    		}
    		sort(a, a+n);
    
    		dv[0]= 0;
    		vis[0]= 1;
    		for (int i= 0; i< n; ++i){
    			int t_st= st ^ (1<<a[i]);
    			int drop= 0;
    			ck[a[i]]= 0;
    			drop|= (1<<i);
    			for (int j= i+1; j< n; ++j){
    				int flag= 1;
    				if (0== a[j]%a[i]){
    					flag= 0;
    				}
    				for (int p= a[j]-a[i]; p> 1 && flag; p-= a[i]){
    					if (!ck[p]){
    						flag= 0;
    					}
    				}
    				if (!flag){
    					t_st^= (1<<a[j]);
    					ck[a[j]]= 0;
    					drop|= 1<<j;
    				}
    			}
    
    			if (!DP(t_st)){
    				ans.push_back(a[i]);
    			}
    			vis[t_st]= 1;
    			for (int k= i; k< n; ++k){
    				if (drop & (1<<k)){
    					ck[a[k]]= 1;
    				}
    			}
    		}
    		printf("Test Case #%d
    ", ++kase);
    		if (ans.empty()){
    			printf("There's no winning move.");
    		}
    		else{
    			printf("The winning moves are:");
    			int sz= ans.size();
    			for (int i= 0; i< sz; ++i){
    				printf(" %d", ans[i]);
    			}
    		}
    		putchar('
    ');
    		putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    linux环境下安装nginx步骤
    时间戳—时间互转 java
    redis配置中踩过的坑
    在Windows端安装kafka 提示错误: 找不到或无法加载主类 的解决方案
    Windows平台kafka环境的搭建
    在windows上搭建redis集群(redis-cluster)
    身份证号打码隐藏
    PIL获取图片亮度值的五种方式
    Python文件排序
    PIL
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/14706602.html
Copyright © 2020-2023  润新知