题解 CF1154F 【Shovels Shop】
\[\huge\texttt{Description}
\]
日期 | \(\texttt{2020}\)年\(\texttt{9}\)月\(\texttt{8}\)日 |
---|---|
编号 | \(\texttt{CF1154F}\) |
算法 | Dp、前缀和与差分、贪心 |
来源 | 无名小题 |
\[\huge\texttt{Solution}
\]
这道题目我们可以用\(Dp\)来解决。
我们容易想到这道题目的一个贪心:买最便宜的那几双鞋。
这应该是不难想的。
\(Dp\)题,我们就得设状态。
我们也不难想到,可以设\(Dp_i\)表示前\(i\)双鞋的\(Cost_{Min}\)。
然后应该就比较好转移了。
首先,我们的\(Dp_i\)一定是从前面的一个\(Dp_j\)转移过来。
然后略加思考,用一个前缀和,算出\(Dp_i\)比\(Dp_j\)要多付的钱,转一下即可。
转移方程就是:
\[Dp_i=\min_{j=0}^{i-1}\{Dp_j+Prefix_i-Prefix_{j+Free_{i-j}}\};
\]
\[\huge\texttt{Code}
\]
#include<bits/stdc++.h>
using namespace std;
int Total,Sale,Buy;
int Array[200001];
int Prefix[200001];
int Free[200001];
int Dp[200001];
int main(void)
{
register int i,j;
cin>>Total>>Sale>>Buy;
for(i=1;i<=Total;i++)
{
cin>>Array[i];
}
sort(Array+1,Array+Total+1);
for(i=1;i<=Total;i++)
{
Prefix[i]=Prefix[i-1]+Array[i];
}
for(i=1;i<=Sale;i++)
{
register int X,Y;
cin>>X>>Y;
Free[X]=max(Free[X],Y);
}
for(i=1;i<=Buy;i++)
{
Dp[i]=0x7ffffff;
}
Dp[0]=0;
for(i=1;i<=Buy;i++)
{
for(j=0;j<i;j++)
{
Dp[i]=min(Dp[i],Dp[j]+Prefix[i]-Prefix[j+Free[i-j]]);
}
}
cout<<Dp[Buy]<<endl;
return 0;
}
不要妄图追上西坠的太阳,而是要在黎明前就等着它!