生活随笔
收集整理的這篇文章主要介紹了
【洛谷4005】小Y和地铁(搜索)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【洛谷4005】小Y和地鐵(搜索)
題面
洛谷
有點長。
題解
首先對于需要被鏈接的兩個點,樣例中間基本上把所有的情況都給出來了。
但是還缺了一種從下面繞道左邊在從整個上面跨過去在從右邊繞到下面來的情況(從反過來是一樣的)
然后把所有方法分類之后發現實際上只有\(4\)種決策。
而\(4\)種決策中,兩兩一組,可以發現對于后面結果的影響是相同的,
那么只需要貪心的考慮選擇兩種決策的較優值。
所以只剩下兩種方法了,直接爆搜+最優性剪枝,拿個二進制什么的狀壓一下計算貢獻,
時間復雜度\(O(2^{n/2})\)
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAX 50
inline int read()
{int x=0;bool t=false;char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=true,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return t?-x:x;
}
int cnt[1<<22],n,m,ans;
int a[MAX],l[MAX],r[MAX],c[MAX],b[MAX],st[MAX],lst[MAX];
void dfs(int x,int S,int tot)
{if(tot>=ans)return;if(x==m){ans=tot;return;}int s=cnt[st[x]&S];dfs(x+1,S|(1<<x),tot+min(s,b[x]-s));dfs(x+1,S,tot+min(c[x]-s,b[x]-c[x]+s));
}
int main()
{for(int Cases=read(),mx=0;Cases;--Cases){n=read();m=0;ans=1e9;for(int i=mx;i<1<<(n/2);++i)cnt[i]=cnt[i>>1]+(i&1);mx=max(mx,1<<(n/2));for(int i=1;i<=n;++i)a[i]=read(),lst[i]=b[i]=c[i]=st[i]=0;for(int i=n;i;--i)if(!lst[a[i]])lst[a[i]]=i;else l[m]=i,r[m]=lst[a[i]],++m;reverse(&l[0],&l[m]);reverse(&r[0],&r[m]);for(int i=0;i<m;++i)for(int j=0;j<i;++j)if(r[j]>l[i]){++b[i];if(r[j]<r[i])st[i]|=1<<j,++c[i];}dfs(0,0,0);printf("%d\n",ans);}return 0;
}
轉載于:https://www.cnblogs.com/cjyyb/p/9552076.html
總結
以上是生活随笔為你收集整理的【洛谷4005】小Y和地铁(搜索)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。