这次比赛大的太爽了,只有两道题没有做出来。
F题 Three displays:
开始的时候看到n最大的取值是3000,便用了暴力循环,结果超时了,看完题解才想到用dp,之前也确实没有接触过dp;
思路:用dp[i][2]表示以i结尾的前i台显示器中满足题意且花费最少的两台的费用,dp[i][2]=min(dp[i][2],c[j]+c[i]),再用dp[i][3]表示以i结尾的前i台显示器中满足题意且花费最少的三台显示器的费用,dp[i][3]=min(dp[i][3],c[i]+dp[i][2]),这里有一个问题,因为我们取得是最小值,怎样才能保证do数组的值足够大,学到了memset函数的新用法:
memset(dp,127,sizeof(dp)) 将dp数组的值全部置为2139062143,int范围内很大的一个数
memset(dp,128,dizeof(dp)) 将dp数组里面的值全部置为-2139062144,int范围内很小的一个数。
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define Max 3000+8
int main()
{
int n,i,j,k;
ll dp[Max][4];
ll ans;
ll mmax=3e11+8;
ans=mmax;
memset(dp,127,sizeof(dp));
cin>>n;
ll a[Max],c[Max];
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<n;i++)
{
cin>>c[i];
for(j=0;j<i;j++)
{
if(a[j]<a[i])
{
dp[i][2]=min(dp[i][2],c[i]+c[j]);
dp[i][3]=min(dp[i][3],c[i]+dp[j][2]);
ans=min(ans,dp[i][3]);
}
}
}
if(ans==mmax)
{
cout<<-1<<endl;
}
else
{
cout<<ans<<endl;
}
return 0;
}