hdoj 4272 LianLianKan 数据太水

点击打开链接

题意:

给出一个序列,其中距离不超过6的两个相同的数字可以消除掉(从上往下消,输入是从底向上的),问能不能全部消除。


思路:

状压dp http://www.cnblogs.com/swm8023/archive/2012/09/10/2679455.html

因为最坏情况下,它后面的四个数字能被它前面的四个数字消掉,这样它就能和原来是它后面的第9个元素相消了,最多10个状态


状态转移:

如果st的第1说明这一位位为0,已经被消掉,d[i][st]=dp(i+1,next(st))。

如果第1为为1,向后连续找至多五个为1的位,比较是否和第一位数字相同,如果相同,就将st的这两位置为0,然后

d[i][st]=d(i+1,next(newst)),newst=st&~1&~(1<<k),其中x[k]==x[i]。

next(st)这个函数是求将st传递到下一个位置时的状态,如果(n-(p+1) > 9) st=1<<9|st>>1,否则st=st>>1,因为只有当后面数字多于10个时,才会有新的数字加入到状态中。

代码一:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e3+10;
16 
17 int n;
18 ll a[maxn];
19 int dp[maxn][1<<10],full;
20 
21 int nx(int p,int st){
22     if(n-(p+1) > 9) return (1<<9) | (st>>1);
23     else return st>>1;
24 }
25 
26 int dfs(int p,int st){
27     if(p == n) return st==0;
28     if(dp[p][st] != -1) return dp[p][st];
29     dp[p][st] = 0; // 二维 表示在p这个位置[保证可以记忆化,不被覆盖] 从p开始的10个数字的状态为st时是否可消
30 
31     if((st&1) == 0) dp[p][st] = dfs(p+1,nx(p,st));
32     else{
33         int cnt = 0;
34         for(int i=1; i<10; i++){
35             if((1<<i & st) == (1<<i)){
36              // if (1<<i&st){
37                  // cout << "aa " << i << " " << st << " " << (1<<i&st) << endl;
38                 cnt++;
39                 if(cnt > 5) break;
40                 if(a[p] == a[p+i]){
41                     int newst = st & ~(1<<i) & ~1;
42                     if(dfs(p+1,nx(p,newst))){
43                         dp[p][st] = 1;
44                         break;
45                     }
46                 }
47             }
48         }
49     }
50     return dp[p][st];
51 }
52 
53 int main(){    
54     while(scanf("%d",&n) != EOF){
55         memset(dp,-1,sizeof(dp));
56         for(int i=1; i<=n; i++)
57             a[n-i] = read();
58         full = (1<<min(n,10)) - 1;
59 
60         cout << dfs(0,full) << endl;        
61     }
62 
63     return 0;
64 }

 

代码二: 直接dfs模拟

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define mp(x,y) make_pair(x,y)
 6 const int INF = 0x3f3f3f3f;
 7 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 8 inline ll read(){
 9     ll x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 //////////////////////////////////////////////////////////////////////////
15 const int maxn = 1e3+10;
16 map<int,int> mp;
17 map<int,int>::iterator it;
18 int a[maxn],used[maxn];
19 
20 int dfs(int n){
21     while(n>0 && used[n]) n--;
22     if(n==0) return 1;
23     if(n==1) return 0;
24     int i = 0;    
25     int j = n-1;
26     while(i<=5){
27         if(j<=0) return 0;
28         if(used[j]) {
29             j--;
30             continue;
31         }
32         if(a[n] == a[j]){
33             used[j] = 1;
34             if(dfs(n-1)) return 1;
35             used[j] = 0;
36         }
37         i++;
38         j--;
39     }
40     return 0;
41 }
42 
43 int main(){
44     int n;
45     while(scanf("%d",&n)!=EOF){
46         mp.clear();
47         mem(used);
48         for(int i=1; i<=n; i++){
49             a[i] = read();
50             mp[a[i]]++;
51         }
52 
53         int flag = 1;
54         for(it=mp.begin(); it!=mp.end(); it++){
55             if(it->second % 2){
56                 flag = 0;
57                 break;
58             }
59         }
60         if(!flag){
61             cout << 0 << endl;
62             continue;
63         }
64         // cout << 1 << endl;
65         cout << dfs(n) << endl;
66     }
67 
68 
69     return 0;
70 }

 

posted @ 2017-02-24 15:00  _yxg123  阅读(142)  评论(0)    收藏  举报