区间dp
人生中首次写区间dp的题目,关键是写之前根本不知道区间dp这回事,结果就是浪费了一下午时间也没写出来。
题目让在一段区间上,给定需要分割的点和一个价值计算方法,问最小价值。开始时总纠结于每一刀的状态,其实压根不用如此,所有需要切割的点都已经知道,只要切完就行,何必纠结于第几刀的问题。按照区间dp的思想,假设有c【1】到c【10】,十个切割点,那么,设dp【i】【t】为i到t已经切好的最小话费,则dp【0】【l】=dp【0】【c【i】】+dp【c【i】】【l】+l-0(1<i=<=10);如此递归,即可求解。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[55][55];
int mark[55][55];
int c[55];
int l,n;
int min(int a,int b)
{
return a>b?b:a;
}
int intervaldp(int l,int r)
{
if (dp[l][r]!=0||l+1>=r)
return dp[l][r];
mark[l][r]=1;
dp[l][r]=99999999;
for (int i=l+1;i<r;i++)
dp[l][r]=min(dp[l][r],intervaldp(l,i)+intervaldp(i,r)+c[r]-c[l]);
return dp[l][r];
}
int main()
{
while (cin>>l&&l)
{
cin>>n;
for (int i=1;i<=n;i++)
cin>>c[i];
c[0]=0;
n++;
c[n]=l;
memset(dp,0,sizeof(dp));
memset(mark,0,sizeof(mark));
sort(c+1,c+n+1);
intervaldp(0,n);
cout<<"The minimum cutting is "<<dp[0][n]<<"."<<endl;
}
return 0;
}