《厦门大学“网宿杯“17届程序设计竞赛决赛》

E:

思路:

想到了三分加最短路来着,没敢写,因为不知道为什么证明满足三分。

显然求最大值是凸函数的极值。

注意点:用非准确范围来控制精度。

然后这是凸函数的三分.

Code:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> pii;
const int N = 2e5+5;
const int M = 1e6+5;
const int Mod = 1000009;
#define pi acos(-1)
#define INF 1e18
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
struct Node{int to,k,b;};
vector<Node> G[N];
int n,m,h;
LL dis[N];
LL check(int x)
{
    for(int i=1;i<=n;++i) dis[i] = INF;
    dis[1] = 0;
    priority_queue<pii,vector<pii>,greater<pii> >Q;
    Q.push(pii(0,1));
    while(!Q.empty())
    {
        int u = Q.top().second;
        LL d = Q.top().first;
        Q.pop();
        if(dis[u] < d) continue;
        for(auto t:G[u])
        {
            int v = t.to,k = t.k,b = t.b;
            if(dis[v] > dis[u]+1LL*k*x+b)
            {
                dis[v] = dis[u]+1LL*k*x+b;
                Q.push(pii(dis[v],v));
            }
        }
    }
    return dis[n];
}
int main()
{
    sddd(n,m,h);
    while(m--)
    {
        int u,v,k,b;
        sdd(u,v);sdd(k,b);
        G[u].push_back(Node{v,k,b});
    }
    int L = 0,r = h;
    while(r-L > 10)
    {
        int mid = L+r>>1;
        int smid = mid+r>>1;
        if(check(mid) > check(smid)) r = smid;
        else L = mid;
    }
    LL ans = -INF;
    for(int i=L;i<=r;++i) ans = max(ans,check(i));
    plr(ans);
    system("pause");
    return 0;
}
View Code

F:

思路:

手动打表

1  2

2  1 3

3  1 1 4
   2 2 2

4  1 1 1 5

5  1 1 1 1 6
   2 2 2 2 2

6  1 1 1 1 1 7
 
7  1 1 1 1 1 1 8
   2 2 2 2 2 2 2

8  1 1 1 1 1 1 1 9
嗯,很明显了。
奇数时为1 1 ... n+1和 2 2 2 2 2.. 2
偶数时为1 1 ... n+1
注意特判下1
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<LL,int> pii;
const int N = 2e5+5;
const int M = 1e6+5;
const int Mod = 1000009;
#define pi acos(-1)
#define INF 1e18
#define INM INT_MIN
#define pb(a)  push_back(a)
#define mk(a,b) make_pair(a,b)
#define dbg(x) cout << "now this num is " << x << endl;
#define met0(axx) memset(axx,0,sizeof(axx));
#define metf(axx) memset(axx,-1,sizeof(axx));
#define sd(ax) scanf("%d",&ax)
#define sld(ax) scanf("%lld",&ax)
#define sldd(ax,bx) scanf("%lld %lld",&ax,&bx)
#define sdd(ax,bx) scanf("%d %d",&ax,&bx)
#define sddd(ax,bx,cx) scanf("%d %d %d",&ax,&bx,&cx)
#define sfd(ax) scanf("%lf",&ax)
#define sfdd(ax,bx) scanf("%lf %lf",&ax,&bx)
#define pr(a) printf("%d\n",a)
#define plr(a) printf("%lld\n",a)
int main()
{
    int n;sd(n);
    if(n&1)
    {
        for(int i=1;i<n;++i) printf("1 ");
        int t = n+1;pr(t);
        if(n != 1) for(int i=1;i<=n;++i) printf("2%c",i==n?'\n':' ');
    }
    else 
    {
        for(int i=1;i<n;++i) printf("1 ");
        int t = n+1;pr(t);
    }
    system("pause");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/zwjzwj/p/12994756.html