URAL 1152 False Mirrors

URAL 1152

思路:

1.状压dp+记忆化搜索

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int INF=0x3f3f3f3f;
int dp[(1<<20)+5];
int a[25];
int n;
int dfs(int sum,int sta){
    if(dp[sta]!=INF)return dp[sta];
    for(int i=0;i<n;i++){
        if(sta&(1<<i)){
            int temp=sta-(1<<i);
            int tsum=sum-a[i];
            int l=(i-1+n)%n;
            int r=(i+1)%n;
            if(sta&(1<<l))temp-=1<<l,tsum-=a[l];
            if(sta&(1<<r))temp-=1<<r,tsum-=a[r];
            dp[sta]=min(dp[sta],dfs(tsum,temp)+tsum);
        } 
    }
    return dp[sta];
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int sum=0;
    mem(dp,INF);
    dp[0]=0;
    cin>>n;
    for(int i=0;i<n;i++)cin>>a[i],sum+=a[i];
    cout<<dfs(sum,(1<<n)-1)<<endl;
    return 0;
} 

2.dfs+剪枝

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=30;
const int INF=0x7f7f7f7f;
int a[N],sum[N];
bool vis[N];
int ans=INF,n;
void dfs(int res,int t){
    if(t>=ans)return ;//剪枝
    if(res==0){
        ans=min(ans,t);
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            int l=i-1;
            int r=i+1;
            if(l==0)l=n;
            if(r==n+1)r=1;
            if(vis[l])l=25;
            if(vis[r])r=25;
            vis[l]=vis[i]=vis[r]=true;
            dfs(res-a[l]-a[i]-a[r],t+res-a[l]-a[i]-a[r]);
            vis[l]=vis[i]=vis[r]=false;
        }
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int sum=0;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
    dfs(sum,0);
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2018-01-28 11:00  Wisdom+.+  阅读(157)  评论(0编辑  收藏  举报