这道题在时间上卡了常数因子,所以用记忆化搜索的方式无法AC。常数因子来自于递归调用所带来的时间开销
记忆化搜索的代码:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define LEN 1000 #define MMAX 99999999 #define MIN(A,B) (A<B?A:B) int num[LEN]; int d[LEN][LEN]; int n; int dp(int s, int e) { int i; int tmp = MMAX; if(-1 != d[s][e]) return d[s][e]; for(i = 0; i < n; i++) { if(num[i] > s && num[i] < e) { tmp = MIN(tmp, dp(s, num[i])+dp(num[i], e)+(e-s)); } } if(MMAX == tmp) { d[s][e] = 0; return 0; } d[s][e] = tmp; return d[s][e]; } int main() { int i, len; int _min = MMAX; while(scanf("%d", &len), len != 0) { scanf("%d", &n); memset(d, -1, sizeof(d)); for(i = 0; i < n; i++) { scanf("%d", &num[i]); } printf("The minimum cutting is %d.\n", dp(0, len)); } return 0; }
非记忆化搜索的代码:
#include <stdio.h> #include <string.h> #define MAX 100 int table[MAX][MAX]; int main() { int l; while(1) { scanf("%d",&l); if(l==0)break; int n,i,j,k,a[MAX],min,t; scanf("%d",&n); for(i=1;i<=n;i++)scanf("%d",&a[i]); a[0]=0;a[n+1]=l; for(i=0;i<=n;i++)table[i][i+1]=0; for(i=2;i<=n+1;i++) { for(j=0;i+j<=n+1;j++) { min=100000; for(k=j+1;k<j+i;k++) if(min>table[j][k]+table[k][j+i]) min=table[j][k]+table[k][j+i]; table[j][i+j]=min+a[j+i]-a[j]; } } printf("The minimum cutting is %d.\n",table[0][n+1]); } return 0; }