主题思想: 动态规划:
动态规划,下标一般从1开始。
下面是状态转移方程的思考过程。
首先dp数组存放最小值,一般求什么dp数组放什么。
那么dp数组是一维还是二维的呢? dp[i][j] 表示前j个perals类中买共分i个类买的。这样想起来很麻烦。
令dp[i]表示,前i个类全部买第i个类。
所以初始化:
dp[i]=(sum[i]+10)*p[i];
dp[i] 可以优化, 即前i个类,一部分全买第j个类(j<=i) 另一部分,j..i这些买第i个类。
dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*p[i]);
AC代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=110;
const int INF=0x3fffffff;
int a[maxn];
int p[maxn];
int sum[maxn];
int dp[maxn]; //dp[i] means buy all buy i category
int main()
{
int T;
scanf("%d",&T);
int c;
while(T--){
scanf("%d",&c);
sum[0]=0;
dp[0]=0;
//usually the in dp ,the index is start from 1
for(int i=1;i<=c;i++){
scanf("%d%d",&a[i],&p[i]);
sum[i]=sum[i-1]+a[i];
dp[i]=(sum[i]+10)*p[i];
}
for(int i=1;i<=c;i++){
for(int j=1;j<=i;j++){
dp[i]=min(dp[i],dp[j]+(sum[i]-sum[j]+10)*p[i]);
}
}
printf("%d\n",dp[c]);
}
return 0;
}