【DP】UVA 10003 Cutting Sticks 类似矩阵链乘
记忆化搜索
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <map> #define IN freopen ("in.txt" , "r" , stdin); #define OUT freopen ("out.txt" , "w" , stdout); typedef long long LL; const int MAXN = 55;//点数的最大值 const int MAXM = 20006;//边数的最大值 const int INF = 11521204; const int mod=1000000007; int dp[MAXN][MAXN],x[MAXN],a; int find(int l,int r) { if(l+1==r) return 0; if(dp[l][r]!=-1) return dp[l][r]; dp[l][r]=INF; for(int i=l+1; i<r; i++) dp[l][r]=min(dp[l][r],find(l,i)+find(i,r)+x[r]-x[l]); return dp[l][r]; } int main() { int n; while(scanf("%d",&n),n) { memset(dp,-1,sizeof(dp)); scanf("%d",&a); x[0]=0; x[a+1]=n; for(int i=1; i<=a; i++) scanf("%d",&x[i]); printf("The minimum cutting is %d.\n",find(0,a+1)); } return 0; }递推
按照r-l的间隔递增转移状态
#include<stdio.h> #include<string.h> int main() { int n,l,i,j,k,c; while (scanf("%d",&l)) { if (l==0) break; scanf("%d",&n); int dp[52][52],p[52]; memset(a,0,sizeof(a)); for (i=1; i<=n; i++) scanf("%d",&p[i]); p[0]=0; p[++n]=l; for (c=2; c<=n; c++)//间隔 for (i=0; i<=n-c; i++) { j=i+c; for (k=i+1; k<j; k++) if (dp[i][j]==0 || dp[i][j]>dp[i][k]+dp[k][j]+p[j]-p[i]) dp[i][j]=dp[i][k]+dp[k][j]+p[j]-p[i]; } printf("The minimum cutting is %d.\n",a[0][n]); } return 0; }