poj1260 dp

来源:互联网 发布:求解无约束优化问题 编辑:程序博客网 时间:2024/05/22 03:47

注意一点:

如果第 i 种珍珠用第 j 种珍珠代替得到最优解, 那么第 i+1~ j - 1种珍珠都应该由第 j 种珍珠代替。

证明:由已知可得第 j 种珍珠一定会买,所以第 i+1~ j - 1种珍珠由 j 以后的珍珠代替不能得到最优,若第 i+1~ j - 1种珍珠

           不由第 j 种代替,那么在第 i+1~ j - 1种珍珠之间必定要买至少一种珍珠 k,那么将第 i 种珍珠由第 k 种珍珠代替,得到

           的解比第 i 种珍珠用第 j 种珍珠代替更优,这与已知矛盾,所以第 i+1~ j - 1种珍珠都应该由第 j 种珍珠代替。

只需确定第 i 种珍珠之前连续几种珍珠由 i 种珍珠代替。

所以得到状态转移方程 dp[ i ]  = min ( dp[ i ], dp[ j ] + ( sum[ i ] - sum[ j ] + 10 ) * cost[ i ] )

其中dp[ i ] 表示买前 i 种珍珠所花的最少钱

       sum[ i ] 表示前 i 种珍珠一共要买多少颗

       cost[ i ]为第 i 种珍珠的单价。

#include <iostream>#include <cstdio>using namespace std;#define M 105#define INF 999999999int c, cost[M], need[M], sum[M], dp[M];inline  int min(int a, int b){    return a < b ? a : b;}int DP(){    int i, j;    dp[0] = 0;    for (i = 1; i <= c; i++) {        dp[i] = INF;        for (j = 0; j <= i; j++)            dp[i] = min (dp[i], dp[j] + (sum[i] - sum[j] + 10) * cost[i]);    }    return dp[c];}int main(){    int t;    scanf ("%d", &t);    while (t--) {       scanf ("%d", &c);       need[0] = cost[0] = sum[0] = 0;       for (int i = 1; i <= c; i++) {           scanf ("%d %d", &need[i], &cost[i]);           sum[i] = sum[i-1] + need[i];       }       printf ("%d\n", DP());    }    return 0;}


原创粉丝点击