noip模拟【2016】

T1

[贪心]

按照等待时间排序,然后记录最大不满意度即可。->复杂度正确O(nlogn),正确性未知。

可以考虑跟全排列的暴力拍一拍。数据好造。暴力好写。

再想5分钟O(n^2)的做法->想不出来。

一遍过小样例和大样例。突然不想拍。写完后面的题再拍。。

今日rank1选手被这题卡了ak哈哈哈。。

 【code】

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define File "transact"
inline void file(){
    freopen(File".in","r",stdin);
    freopen(File".out","w",stdout);
} 
inline int read(){
    int x = 0,f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch=='-')f = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x<<1) + (x<<3) + ch-'0'; ch = getchar();}
    return x*f;
}
const int mxn = 1e5 + 5;
int n;
struct P{
    int t,d;
}p[mxn];

inline bool cmp(P t1,P t2){
    return t1.d < t2.d;
}

int main(){
    file();
    n = read();
    for(int i = 1;i <= n; ++i) p[i].t = read();
    for(int i = 1;i <= n; ++i) p[i].d = read();
    sort(p+1,p+n+1,cmp);
    ll s(0),mx(0);
    for(int i = 1;i <= n; ++i){
        s += (ll)p[i].t;
        if(s > (ll)p[i].d) mx = max(mx,s-(ll)p[i].d);
    }
    printf("%lld\n",mx);
    return 0;
}
View Code

 

 

T2

[拓扑?]

由于每个人接到球之后会把球传给谁是固定的,并且传球的距离也是固定的。

改变接球顺序来改变传球接力最长距离,就只是改变第一个发球人的顺序。

当球要传给一个已经拿到过球的人时,传球停止。

O(n^2)暴力 -> 50pts

可以想到这个图实际上是一棵树(有向)多一条边,要求该图的直径。

一个正确性靠谱但复杂度没了的做法。从每一个入度为零的点出发。

一个复杂度正确正确性未知的做法。建双向边,特殊处理,跑树的直径即可。

那就冷静一下之后写这两个程序。

然后正确性未知的做法果然是个垃圾。

想到实际上就是要处理一个环加上若干枝。

且必定从某个入度为零的点进入遍历。

这个环(少一条边)是无论如何都要遍历一遍的。

枚举断点,取max即可。

 【code】

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define File "pass"
inline void file(){
    freopen(File".in","r",stdin);
    freopen(File".out","w",stdout);
} 
inline int read(){
    int x = 0,f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch=='-')f = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x<<1) + (x<<3) + ch-'0'; ch = getchar();}
    return x*f;
}
const int mxn = 5e5 + 5;
int n;
int in[mxn],cir[mxn];
ll a[mxn],d[mxn],b[mxn],f[mxn]; 

queue<int> q;
bool v[mxn];
ll tot(0),sum(0),ans(0);

int main(){
    file();
    n = read();
    for(int i = 1;i <= n; ++i){
        a[i] = read(),d[i] = read();
        in[a[i]]++;
    }
    for(int i = 1;i <= n; ++i) 
        if(!in[i]) q.push(i);
    
    while(!q.empty()){
        ll x = q.front(); q.pop();
        ll y = a[x];
        f[y] = max(f[y],f[x] + d[x]);
        if(!(--in[y]))    q.push(y);
    }
    
    for(int i = 1;i <= n; ++i){
        if(in[i] && !v[i]){
            ll k = a[i];
            
            cir[++tot] = i;
            b[a[i]] = d[i];
            sum = d[i];
            
            while(k != i){
                v[k] = 1;
                
                cir[++tot] = k;
                b[a[k]] = d[k]; 
                sum += d[k];
                
                k = a[k];                                         
            }//
            for(int j = 1;j <= tot; ++j)
                ans = max(ans,sum + f[cir[j]] - b[cir[j]]);
        }
    } 
    printf("%lld\n",ans);
    return 0;
}
/*
5
2 1
3 2
4 1
2 3
3 3
*/
View Code

 

 

T3

[dp]

考虑最暴力的暴力。

选择在哪一个方格开始游戏O(n^2)

向哪个方向走多少各O(4*n)

走到当前格子之后继续走。。

再次O(4*n)枚举

总共枚举T次。

总复杂度为O(n^2*4^T*n^T) -> 30pts

等哈。这莫不是个dp嘛。

然后就可以满分了。。

 【code】

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define File "coin"
inline void file(){
    freopen(File".in","r",stdin);
    freopen(File".out","w",stdout);
} 
inline ll read(){
    ll x = 0,f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){if(ch=='-')f = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x<<1) + (x<<3) + ch-'0'; ch = getchar();}
    return x*f;
}
const int mxn = 30;
const int mxT = 105;
const int mxW = 155;
int n,C,W,T;
int dx[5] = {-1,1,0,0,0},dy[5] = {0,0,-1,1,0}; 

inline ll min_(ll x,ll y){
    return x < y ? x : y;
}
inline ll max_(ll x,ll y){
    return x > y ? x : y;
}
inline bool ok(int x,int y){
    if(x > 0 && x <= n && y > 0 && y <= n) return true;
    return false;
}
inline int x_(int i,int x,int c){
    if(!c) return x+dx[i];
    return x+2*c*dx[i];
}
inline int y_(int i,int y,int c){
    if(!c) return y+dy[i];
    return y+2*c*dy[i];
}

ll f[mxT][mxn][mxn][mxW];
ll a[mxn][mxn];
ll ans(0);
int main(){
    file();
    n = read(),C = min_(n/2,read()),W = read(),T = read();
///*
    memset(f,0xcf,sizeof f);

    for(int i = 1;i <= n; ++i)
        for(int j = 1;j <= n; ++j)
            f[0][i][j][0] = 0;
    
    for(int t = 1;t <= T; ++t){
        for(int i = 1;i <= n; ++i)
            for(int j = 1;j <= n; ++j)
                a[i][j] = read();
        
        for(int x = 1;x <= n; ++x)
            for(int y = 1;y <= n; ++y)
                for(int s = 0;s <= W; ++s)
                    for(int i = 0;i < 5; ++i)
                        for(int c = 0;c <= min_(C,s) && ok(x_(i,x,c),y_(i,y,c)) && (i!=4||!c); ++c)
                            f[t][x][y][s] = max_(f[t][x][y][s],f[t-1][x_(i,x,c)][y_(i,y,c)][s-c] + a[x][y]);        
    }
    
    for(int i = 1;i <= n; ++i)
        for(int j = 1;j <= n; ++j)
            for(int k = 0;k <= W; ++k)    
                ans = max_(ans,f[T][i][j][k]);
    printf("%lld\n",ans);             

    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/ve-2021/p/11357083.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NOI(全国青少年信息学奥林匹克竞赛)模拟赛的测试数据是指用于评测参赛选手的程序的输入和对应的输出。测试数据是非常重要的,因为它决定了参赛选手的程序能否正确地解决问题。 在NOI模拟赛中,测试数据具有以下特点: 1.充分覆盖:测试数据应涵盖各种可能的输入情况,包括边界条件和极端情况。通过提供不同的测试数据,可以考察选手对问题的全面理解和解决能力。 2.随机性和均衡性:为了公平起见,测试数据应该是随机生成的,而不是针对某个特定算法或解法设计的。同时,测试数据应该是均衡的,即各种情况的概率应该大致相等,以避免偏向某些解法。 3.合理性和可行性:测试数据应该是合理和可行的,即符合题目要求的输入数据,并且是选手能够通过编写程序来处理的。测试数据应该考虑到程序的限制和时间复杂度,以充分测试选手的编程能力。 NOI模拟赛的测试数据通常由经验丰富的考题组负责生成。他们会根据题目的要求和限制,设计出一组合理、充分、随机和均衡的测试数据,以确保参赛选手的程序在各种情况下都能正确运行,并且能通过性能测试。 总之,测试数据在NOI模拟赛中起到了至关重要的作用,它既考察了选手对问题的理解和解决能力,又提高了选手编程的技巧和效率。同时,合理和恰当的测试数据也是公平竞赛的保证,确保每个参赛选手有相同的机会和条件进行竞争。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值