hdoj 4272 LianLianKan 数据太水
生活随笔
收集整理的這篇文章主要介紹了
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 }?
轉載于:https://www.cnblogs.com/yxg123123/p/6827697.html
總結
以上是生活随笔為你收集整理的hdoj 4272 LianLianKan 数据太水的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机音乐播放器哪个音质最好?
- 下一篇: binutils工具集之---ar