记忆化搜索
#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
//const int N = 1e5 + 5;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
ll fast_pow(ll a,ll b){
ll ans = 1;
while(b){
if(b&1)ans = (ans * a)%mod;
a = (a * a)%mod;
b>>=1;
}
return (ans%mod);
}
typedef pair<int,int> pii;
const int N = 55;
int dp[N][N];
int l,n;
int a[N];
int dfs(int l,int r){
if(dp[l][r] != INF)return dp[l][r];
if(l == r - 1)return 0;
int ans = INF;
for(int i = l + 1;i < r;i++)
ans = min(dfs(l,i) + dfs(i,r) + a[r]- a[l],ans);
dp[l][r] = ans;
//cout<<"L : "<<l<<" R : "<<r<<" "<<dp[l][r]<<endl;
return ans;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#if DBG
freopen("input.txt","r",stdin);
#endif
while(cin>>l){
if(l == 0)break;
cin>>n;
for(int i = 2;i <= n + 1;i++)cin>>a[i];
for(int i = 1;i <= n + 2;i++)
for(int j = 1;j <= n + 2;j++)dp[i][j] = INF;
a[1] = 0,a[n + 2] = l;
printf("The minimum cutting is %d.\n",dfs(1,n + 2));
}
return 0;
}
递推思路:
对一个长的区间,需要事先知道比它短的区间的最优解,才能更新这个长的区间,因此,可以根据区间长度枚举。
#include<bits/stdc++.h>
#define debug(x) cout<<#x<<" is "<<x<<endl
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define DBG 0
const int N = 50 + 5;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const ll LLINF = (1LL<<60);
using namespace std;
const int mod = 998244353;
ll fast_pow(ll a,ll b){
ll ans = 1;
while(b){
if(b&1)ans = (ans * a)%mod;
a = (a * a)%mod;
b>>=1;
}
return (ans%mod);
}
typedef pair<int,int> pii;
int dp[N][N];
int a[N];
int l,n;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#if DBG
freopen("input.txt","r",stdin);
#endif
while(cin>>l){
if(l == 0)break;
cin>>n;
for(int i = 1;i <= n + 2;i++)for(int j = 1;j <= n+ 2;j++)dp[i][j] = INF;
for(int i = 2;i <= n + 1;i++){
cin>>a[i];
dp[i - 1][i] = 0;
}
a[1] = 0,a[n + 2] = l;
dp[n + 1][n + 2] = 0;
for(int len = 2;len <= n + 1;len++){
for(int i = 1;i + len <= n + 2;i++){
for(int j = i + 1;j < i + len;j++){
dp[i][i + len] = min(dp[i][i + len],dp[i][j] + dp[j][i + len] + a[i + len] - a[i]);
//cout<<"L : "<<i<<" R : "<<i + len <<" "<<dp[i][i + len]<<endl;
}
}
}
printf("The minimum cutting is %d.\n",dp[1][n + 2]);
}
return 0;
}