区间dp

区间DP

    • 区间DP
      • 注意点
      • 例题:
        • 1.最优矩阵链乘
        • 2.UVA 10003 Cutting Sticks

注意点

区间dp与一般的dp有所区别,若使用递推的方法,需要注意根据dp[i][j] 
中j-i递增的顺序来递推。

例题:

1.最优矩阵链乘

  
  
  
  
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. #include <string>
  5. #include <map>
  6. #include <cmath>
  7. #define INF 1<<30
  8. using namespace std;
  9. int p[105],f[105][105];
  10. int min(int a, int b)
  11. {
  12. return a<b?a:b;
  13. }
  14. int main()
  15. {
  16. int n;
  17. while(~scanf("%d",&n)&&n)
  18. {
  19. for(int i=0; i<=n; i++)
  20. cin>>p[i];
  21. for(int i=1; i<=n; i++)
  22. {
  23. for(int j=0; j<=n; j++)
  24. f[i][j]=INF;
  25. f[i][i]=0;
  26. f[i][i+1]=p[i-1]*p[i]*p[i+1];
  27. }
  28. for(int l=2; l<=n; l++) ///递推的过程 记住要按照j-i递增的顺序递推
  29. for(int i=1; i+l<=n; i++)
  30. {
  31. int j=i+l;
  32. for(int k=i; k<=j; k++)
  33. f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+p[i-1]*p[k]*p[j]);
  34. }
  35. cout<<f[1][n]<<endl;
  36. }
  37. return 0;
  38. }

2.UVA 10003 Cutting Sticks

  
  
  
  
  1. #include <cstdio>
  2. #include <iostream>
  3. #include <cstring>
  4. using namespace std;
  5. #define maxn 100000
  6. int p[55],dp[55][55];
  7. int main()
  8. {
  9. int L,n;
  10. while(cin>>L&&L)
  11. {
  12. memset(dp,0,sizeof(dp));
  13. cin>>n;
  14. for(int i=1; i<=n; i++)
  15. cin>>p[i];
  16. p[0]=0,p[n+1]=L;
  17. for(int l=2; l<=n+1; l++)
  18. for(int i=0; i+l<=n+1; i++)
  19. {
  20. int j=i+l;
  21. dp[i][j]=maxn;
  22. for(int k=i; k<j; k++)
  23. dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+p[j]-p[i]);
  24. }
  25. cout<<"The minimum cutting is "<<dp[0][n+1]<<"."<<endl;
  26. }
  27. }

你可能感兴趣的:(总结,ACM)