首页 > 代码库 > Uva 10003 Cutting Sticks (类似于最优矩阵连乘的dp)
Uva 10003 Cutting Sticks (类似于最优矩阵连乘的dp)
题意:有一根长度为L的木棍,和n个切割点的位置(按照从小到大排序),你的任务是在这些切割点的位置把棍子切成n+1份,使得总切割费用最小。每次切割的费用等于被切的木棍长度
思路:这道题与最优矩阵连乘的思想一样,那就是分析最优子结构,再根据子结构来定义状态,首先我们假定第一次分割的最优方案是在k处分割,得到0~k与k~L两段木棍,那么如何最优分割0~k与0~L就是它的子问题,我们根据子问题定义状态d(i,j)是分割从割点i到割点j的最优方案,状态转移方程 d(i,j)=min{d(i,k)+d(k,j)+(cut[j]-cut[i])}(其中i<k<j),接下来是确定边界,d(i,i)=0 和 d(i,i+1)=0,并注意赋初值INF
代码:
#include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #define INF 0x3f3f3f3f using namespace std; int d[55][55]; int cut[55]; bool visit[55][55]; int L,n; int dp(int i,int j) { if((j-i)<=1) return 0; if(visit[i][j]==true) return d[i][j]; visit[i][j]=true; for(int k=i+1;k<j;k++) d[i][j]=min(d[i][j],dp(i,k)+dp(k,j)+(cut[j]-cut[i])); return d[i][j]; } int main(int argc, char const *argv[]) { while(cin>>L&&L) { cin>>n; for(int i=1;i<=n;i++) { scanf("%d",&cut[i]); } cut[0]=0; cut[n+1]=L; memset(visit,false,sizeof(visit)); memset(d,INF,sizeof(d)); int ans=dp(0,n+1); cout<<"The minimum cutting is "<<ans<<"."<<endl; } return 0; }
Uva 10003 Cutting Sticks (类似于最优矩阵连乘的dp)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。