2020年10月9日个人赛

这次比赛大的太爽了,只有两道题没有做出来。

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;

}

原文地址:https://www.cnblogs.com/chengxvzhishen/p/13835857.html