hdu1300

链接:hdu1300

题解

  • 其实这个数据量根本不需要优化2333
  • dp[i]表示前i个数得到的最大价值
  • 然后很容易就可以得到转移方程,每次选j~i这个级别的放在一起
  • dp[i]=min(dp[j-1]+(sum[i]-sum[j-1])*p[i])
  • 虽然到这里就可以AC了,还是考虑下斜率优化
  • 考虑k<j,j比k更优

  • 最后…数据有bug,排序会wa(或许是std挂了?逃)

dp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
using namespace std;
const int N=1e3+7;
typedef pair<ll,ll> s;
s a[N];
ll dp[N],sum[N];
int n,T;
inline int cmp(s x,s y){return x.first<y.first;}
inline void init(){
scanf("%d",&n);
rep(i,1,n)scanf("%lld%lld",&a[i].first,&a[i].second);
//sort(a+1,a+n+1,cmp);
rep(i,1,n){
sum[i]=a[i].first;
dp[i]=dp[i-1]+(sum[i]+10)*a[i].second;
sum[i]+=sum[i-1];
}
}
int main(){
scanf("%d",&T);
while(T--){
init();
rep(i,1,n)rep(j,1,i)dp[i]=min(dp[i],dp[j-1]+(sum[i]-sum[j-1]+10)*a[i].second);
printf("%lld\n",dp[n]);
}
return 0;
}

斜率优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
#define repd(i,x,y) for(register int i=x;i>=y;--i)
#define ll long long
using namespace std;
const int N=1e3+7;
typedef pair<ll,ll> s;
s a[N];
ll dp[N],sum[N];
int n,T,q[N];
inline int cmp(s x,s y){return x.first<y.first;}
inline void init(){
scanf("%d",&n);
rep(i,1,n)scanf("%lld%lld",&a[i].first,&a[i].second);
//sort(a+1,a+n+1,cmp);
rep(i,1,n)sum[i]=a[i].first+sum[i-1];
}
inline ll Y(int a,int b){return dp[a]-dp[b];}
inline ll X(int a,int b){return sum[a]-sum[b];}
int main(){
scanf("%d",&T);
while(T--){
init();
int head=1,tail=1;
rep(i,1,n){
while(head<tail&&Y(q[head+1],q[head])<a[i].second*X(q[head+1],q[head]))++head;
dp[i]=dp[q[head]]+(sum[i]-sum[q[head]]+10)*a[i].second;
while(head<tail&&Y(q[tail],i)*X(q[tail-1],q[tail])<=Y(q[tail-1],q[tail])*X(q[tail],i))--tail;
q[++tail]=i;
}
printf("%lld\n",dp[n]);
}
return 0;
}