题目链接。
题目大意:
给定一个n,和两个序列a[i], p[i]. a[i] 表示需要购买 i品质 的数量,p[i] i 等级的价格。
1.每个品质都会有不同的价格,价格依据品质上升而上升
2.买一次 i 品质,都要加上10个 i 品质 价格的手续费。
3.可一用高品质的代替低品质.
求最少的花费.
分析:
这题就简单地矩阵链乘法(《算法导论》第15章,动态规划)。
用 dp[i][j] 表示购买 i 品质到 j 的最少的花费.
dp[i][j] = min{dp[i][k]+dp[k+1][j]), i<=k<j.
代码如下:
#include <iostream> #include <cstdio> using namespace std; const int maxn = 1500; int a[maxn], p[maxn]; int dp[maxn][maxn]; int main(){ int T, n; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=0; i<n; i++) scanf("%d%d", &a[i], &p[i]); //初始化 for(int i=0; i<n; i++) dp[i][i] = (a[i]+10)*p[i]; for(int l=2; l<=n; l++) { //l表示问题的长度 for(int i=0; i<n-l+1; i++) { int j = i+l-1, s=0; //将i~j的都按最高品质j购买 for(int k=i; k<=j; k++) { s += a[k]; } dp[i][j] = p[j]*(s+10); //分解 for(int k=i; k<=j-1; k++) { dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]); } } } printf("%d\n", dp[0][n-1]); } return 0; }