Time limit: 3.000 seconds
Cutting Sticks |
It is easy to notice that different selections in the order of cutting can led to different prices. For example, consider a stick of length 10 meters that has to be cut at 2, 4 and 7 meters from one end. There are several choices. One can be cutting first at 2, then at 4, then at 7. This leads to a price of 10 + 8 + 6 = 24 because the first stick was of 10 meters, the resulting of 8 and the last one of 6. Another choice could be cutting at 4, then at 2, then at 7. This would lead to a price of 10 + 4 + 6 = 20, which is a better price.
Your boss trusts your computer abilities to find out the minimum cost for cutting a given stick.
The next line consists of n positive numbers ci ( 0 < ci < l) representing the places where the cuts have to be done, given in strictly increasing order.
An input case with l = 0 will represent the end of the input.
100 3 25 50 75 10 4 4 5 7 8 0
The minimum cutting is 200. The minimum cutting is 22.
思路就是枚举区间中的一个值进行区间DP。
/* ID: xinming2 PROG: stall4 LANG: C++ */ #include <cstdio> #include <cmath> #include <algorithm> #include <iostream> #include <cstring> #include <map> #include <string> #include <stack> #include <cctype> #include <vector> #include <queue> #include <set> #include <utility> #include <cassert> using namespace std; ///#define Online_Judge #define outstars cout << "***********************" << endl; #define clr(a,b) memset(a,b,sizeof(a)) #define lson l , mid , rt << 1 #define rson mid + 1 , r , rt << 1 | 1 #define mk make_pair #define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++) #define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++) #define REP(i , x , n) for(int i = (x) ; i > (n) ; i--) #define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--) const int MAXN = 15 + 50; const int sigma_size = 26; const long long LLMAX = 0x7fffffffffffffffLL; const long long LLMIN = 0x8000000000000000LL; const int INF = 0x7fffffff; const int IMIN = 0x80000000; #define eps 1e-8 const int mod = (int)1e9 + 7; typedef long long LL; const LL MOD = 1000000007LL; const double PI = acos(-1.0); typedef pair<int , int> pi; #define Bug(s) cout << "s = " << s << endl; ///#pragma comment(linker, "/STACK:102400000,102400000") int dp[MAXN][MAXN] ;///dp[i][j]表示从i到j的最小花费 int a[MAXN] , vis[MAXN][MAXN]; int DP(int i , int j) { if(vis[i][j])return dp[i][j]; vis[i][j] = 1; if(j - i == 1)return 0; int min_i = INF; for(int k = i + 1 ; k < j ; k++) { min_i = min(min_i , DP(i , k) + DP(k , j) + a[j] - a[i]); } dp[i][j] =min_i; return min_i; } int main() { int n , m; while(~scanf("%d" , &n) , n) { clr(dp , 0); clr(vis , 0); scanf("%d" , &m); for(int i = 1 ;i <= m ; i++) { scanf("%d", &a[i]); } a[++m] = n; printf("The minimum cutting is %d.\n" , DP(0 , m)); } return 0; }