[BZOJ2059] Buying Feed

Keywords: C++

Problem surface

John drove to town. He wanted to take V tons of feed home. If he has x tons of feed in his car, it will cost X^2 yuan per kilometer, and D* X^2 yuan for driving D kilometer. John can buy feed from n stores, all of which are on the same axis. The location of the ith store is Xi. The price of feed is Ci yuan per ton, and the stock is Fi. n≤500,k≤10000.

Input format

Line 1: three integers V,E,N

Line 2..N+12..N+1: the three integers in line i+1 represent Xi, Fi, Ci

Output format

An integer representing the minimum cost

Data range

1 ≤ V≤ 10000 , 1 ≤ E ≤ 500 , 1 ≤ N ≤ 500;

0 < Xi < E, 1 ≤ Fi ≤ 10000, 1 ≤ Ci ≤ 10^7

Example

2 5 3
3 1 2
4 1 2
1 1 1
input
 9
output

thinking

First, play a 2D dp to show how much it costs to have j feeds at the ith point.

sort x I once, and then triple cycle dp. The equation is dp[i][j]=min(dp[i][j],dp[i-1][j-k]+a[i].c*k+(a[i].x-a[i-1].x)*(j-k)*(j-k));

Last cout < < DP [n] [v] + (e-A [n]. X) * V * V < < endl; it means the minimum price of the last store at home + 1...n store's minimum value (that is, the minimum value of 1...n)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{int x,f,c;}a[505];
 4 long long v,e,n,dp[505][10005];
 5 bool cmp(node p,node q){return p.x<q.x;}
 6 inline int read(){
 7     int ret=0,f=1;char ch=getchar();
 8     while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
 9     while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
10     return ret*f;
11 }
12 int main(){
13     freopen("d.in","r",stdin);
14     freopen("d.out","w",stdout);
15     v=read();e=read();n=read();
16     memset(dp,0x7f,sizeof(dp));
17     for (int i=1;i<=n;i++) a[i].x=read(),a[i].f=read(),a[i].c=read();
18     sort(a+1,a+n+1,cmp);
19     dp[0][0]=0;
20     for (int i=1;i<=n;i++)
21      for (int j=0;j<=v;j++)
22       for (int k=0;k<=a[i].f&&k<=j;k++)
23       dp[i][j]=min(dp[i][j],dp[i-1][j-k]+a[i].c*k+(a[i].x-a[i-1].x)*(j-k)*(j-k));
24      cout<<dp[n][v]+(e-a[n].x)*v*v<<endl;
25     return 0;
26 }
nv^2 dp

Unfortunately, the above methods will explode

Let's optimize: first of all, regard home as a store, distance as e, inventory as 0, unit price as 0

Then use a deque to save k

I f (j-q.front() > a [i-1]. F) falls behind in pop, because i-1's store inventory is not enough;

If top = q.back(), DP [I-1] [top] - a [I-1]. C * top > = DP [I-1] [J] - w [I-1] * J, pop will fall behind;

int may explode in the process, so long long is on.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct node{long long x,f,c;}a[505];
 4 long long v,e,n,dp[505][10005];
 5 bool cmp(node p,node q){return p.x<q.x;}
 6 int main(){
 7     freopen("d.in","r",stdin);
 8     freopen("d.out","w",stdout);
 9     cin>>v>>e>>n;
10     memset(dp,0x7f,sizeof(dp));
11     for (int i=1;i<=n;i++) cin>>a[i].x>>a[i].f>>a[i].c;
12     n++;
13     a[n]=(node){e,0,0};
14     sort(a+1,a+n+1,cmp);
15     dp[0][0]=0;
16     for (int i=1;i<=n;i++)
17     {
18         deque<long long>q; 
19         for (int j=0;j<=v;j++) 
20         {           
21             while (!q.empty()&&j-q.front()>a[i-1].f) q.pop_front();  
22             if (dp[i-1][j]!=0x7f)
23             {
24                 while (!q.empty()&&dp[i-1][q.back()]-a[i-1].c*q.back()>=dp[i-1][j]-a[i-1].c*j) q.pop_back();
25                 q.push_back(j);
26             }
27             int top=q.front();
28             if (!q.empty()) dp[i][j]=dp[i-1][top]-a[i-1].c*top+(a[i].x-a[i-1].x)*j*j+a[i-1].c*j;
29         }
30     }
31      cout<<dp[n][v]<<endl;
32     return 0;
33 }    

Posted by BrianM on Sat, 04 Jan 2020 08:01:30 -0800