算法总结—区间 DP3+状压 DP1

环形区间 DP

环形区间 DP 断环成链就可以了,答案就可以从 \([1,n],[2,n+1],[3,n+2],\cdots,[n,2n-1]\) 这些区间的答案。

[NOI1995] 石子合并

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[205];
int sum[205];
int dp[205][205];
signed main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
        a[i+n]=a[i];
	}
    for(int i=1;i<=n+n;i++){
		sum[i]=sum[i-1]+a[i];
		for(int j=1;j<=n+n;j++){
			dp[i][j]=1e18;
		}
		dp[i][i]=0;
    }
	for(int len=2;len<=n;len++){
		for(int i=1;i+len-1<=n+n;i++){
			int j=i+len-1;
			for(int k=i;k<j;k++){
				dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
			}
		}
	}
    int Min=1e18;
    for(int i=1;i<=n;i++){
        Min=min(Min,dp[i][i+n-1]);
    }
    cout<<Min<<"\n";
    for(int i=1;i<=n+n;i++){
		sum[i]=sum[i-1]+a[i];
		for(int j=1;j<=n+n;j++){
			dp[i][j]=0;
		}
    }
	for(int len=2;len<=n;len++){
		for(int i=1;i+len-1<=n+n;i++){
			int j=i+len-1;
			for(int k=i;k<j;k++){
				dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
			}
		}
	}
    int Max=-1e18;
    for(int i=1;i<=n;i++){
        Max=max(Max,dp[i][i+n-1]);
    }
    cout<<Max;
    return 0;
}

状压 DP

海贼王之伟大航路

这道题的 \(n\leq 16\),可以尝试用 DFS,但时间复杂度是 \(\mathcal{O}(n!)\) 的。在 DFS 中有许多重复的地方,比如说走过一个点集,且最后停留在一个点,这个情况会被 DFS 好几遍,所以可以把这个答案记下来。

状态

\(dp_{i,j}\) 表示所选集合为 \(i\),最后停留在点 \(j\) 最小的答案(这 \(n\) 个点是 \(0\)\(n-1\))。

答案

\(dp_{2^n-1,n-1}\)

状态转移方程

\(dp_{i,j}=\min\{dp_{i\oplus 2^j,k}+dis_{k,j}\}\),其中 \(i\) 在二进制上的第 \(j\)\(k\)\(1\)

初始值

\(dp_{i,j}=\inf(0\leq i<2^n,0\leq j<n),dp_{1,0}=0\)

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int a[20][20];
int dp[65550][20];
signed main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			cin>>a[i][j];
		}
	}
	int N=1<<n;
	memset(dp,0x3f,sizeof dp);
	dp[1][0]=0;
	for(int i=0;i<N;i++){
		for(int j=0;j<n;j++){
			if((i>>j)&1){
				for(int k=0;k<n;k++){
					if((i>>k)&1){
						dp[i][j]=min(dp[i][j],dp[i^(1<<j)][k]+a[k][j]);
					} 
				}
			}
		}
	}
	cout<<dp[N-1][n-1];
    return 0;
}
posted @ 2025-05-11 18:50  LRRabcd  阅读(7)  评论(0)    收藏  举报