训练日记 2019.9.24 卧槽!简历没写!

2019.9.24 星期二
星期二马上要过完了,一周接近过半了,除去假期,可能还真的没有10周了,都这个速度过下去,那就太好啦。

好吧,昨天晚上半夜被饿醒了,想吃炒米饭,加上室友灯光的影响,自己弄到2点才睡着,今天起来精神状态果然有点飘忽,晚上早些回去休息,下午别睡觉,别养成夜猫子的习惯。今天效率不行,那就不行吧,反正也没什么特别要紧的事情,除了明天的考试,晚上睡觉之前再复习一下即可,没什么好担心的。

今天把ccpc2019的池塘问题写出来了。在?为什么要钓鱼?昨天卡住是因为理不清这个费用和可钓的鱼的数量之间的边际决定条件,今天集中精力,仔细读题,发现忽略了个重要条件,也就是所有的路就是单向边,而且是单源的,从1开始,那就不存在最短路问题了,之前本来还担心自己要不要做一遍Floyd,后来发现这个完全多虑了,直接从1到n枚举一遍路,减掉中间所花的费用就可以实现自由切换鱼塘钓鱼了(我好机智),数据量不大,大概25左右,那就很随意了,我的想法是,每次用优先队列存池塘,动态维护的队列取队首,也就是在枚举的路上可以调到的鱼的当前最大的数目的池塘,钓鱼,减掉,然后再推入优先队列,重复这一过程,然后题目中要求如果有剩余时间,加在最前面的池塘,这个简单,修改下运算符,让所有鱼钓完之后,id小的排前面就行咯。至于在每个池塘花的时间,那就让struct多存一个状态就好了,每次执行完之后因为总的池塘数量是不变的,直接动态更新就行。想好了这些,直接开写代码,写完了,没有报错,输入样例!第一次运行程序的时候傻眼了,耶?这咋这么多鱼呢?标准答案钓上来724条,我弄上来780条。。。。只有样例2对了,后来发现是运算符的逻辑出了一丢丢问题,也不难,解决!然后又又又又出问题了,真够一波三折的,我发现我忘考虑在路上的时间了,饿,这么重要都能忘掉也真是没谁了,都改完之后,屏幕上第一次打出了正确的答案,呵,终于可以了,提交!第一次是Presentation Error,我长出了一口气,因为这个代表答案没错,然后我加了个空行,成功AC!哈哈成功拿下了这道题,提交数目已经变成了73,向着百题大佬努力!!!!

今天才知道原来BZOJ被境外不法分子搞去喝茶了,怪不得hdu晚上要关。

下午发现离散讲到算法分析了,为了方便分析,找重复的元素竟然用O(N^2)的时间,acmer的本能让我真替作者着急,“哎,你这个用动态规划不好么?咱能不能写个哈希表啊?哈希表不行咱动小手用个hashmap也行啊?”然后就是复杂度,基本上手代码多了,只要是什么复杂度,看几个地方自己就一清二楚了,这里不多解释。可能acm到现实用处不大,但是这种时刻记在脑子里的高效的程序设计的思维是受益终身的。

今天没那么多精力继续搞了,明儿还有考试,不能再睡晚了。然后规划一下回去的行程,期望一下未来,不多说了,放题!
题目: POJ1042 Gone Fishing传送门

#include <bits/stdc++.h>
using namespace std;
#define limit 200000 + 5
#define INF 0x3f3f3f3f
#define lch root * 2 + 1
#define rch root * 2 + 2
#define lowbit(i) i&(-i)//一步两步
#define EPS 1e-6
#define ff(a) printf("%d\n",a );
typedef long long ll;
void read(int &x){
    char ch = getchar();x = 0;
    for (; ch < '0' || ch > '9'; ch = getchar());
    for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}//快读
int fish[limit], cost[limit], decr[limit];
int n ;
int stay[limit];
int timeLeft;
struct lake{
    //记录湖的状态
    int id, stay, fish ,decc;//id记录号码,stay初始化为0记录在这个地方呆的时间
    lake() = default;
    lake(int ii , int ff, int dd):id(ii) ,stay(0), fish(ff) , decc(dd){}
    bool operator<(const lake &rhs)const{
        if(fish == rhs.fish){
            return id > rhs.id;//这点主要是为了让所有地方的鱼清空之后把剩余时间分配给前面的湖
        }else{
            return fish < rhs.fish;
        }
    }
};
int solve(){
    priority_queue<lake>q;
    int ans = -INF;//答案初始化为负无穷
    for(int i = 1 ; i <= n ; ++i){//这一层循环是为了给池塘数目设界,比如1-3,在1,12,123停留的情况都要考虑到
        //每走一起枚举一遍
        int tot = timeLeft - cost[i - 1];//总时间,每次走几个湖的问题.预先打表不用挨个算了
        while(!q.empty()){
            q.pop();
        }//把可能的元素剔除,防止干扰判断
        int tmp = 0;
        for(int j = 1 ; j <= i ;++j ){
            q.push(lake(j , fish[j] , decr[j]));//推进去
        }
        while(tot > 0){
            lake cur = q.top();
            //printf("The sample being drawn has the value of %d\n", cur.fish);
            q.pop();
            tmp += cur.fish;
            cur.fish -= cur.decc;
            tot -= 5;
            if(cur.fish < 0) cur.fish = 0;//拨正归零
            cur.stay += 5;
            q.push(cur);//做完dfs再送回去,这里鱼钓完了,所有池塘数目为0,根据运算符规定按id序排列
            // 进行处理是因为刚才重载运算符的时候已经考虑了这种情况,id靠前的优先,无鱼可钓之后
            //自然把时间加到第一个了
        }
        if(tmp > ans){//这里是如果渔获大于原来的才可以更新,等于排除在外
            ans = tmp;
            while(!q.empty()){
                lake now = q.top();
                q.pop();
                stay[now.id] = now.stay;//如果没有了就更新
            }
        }
    }
    return ans;
};
int main(){
    while(scanf("%d" , &n) == 1 && n ){
        scanf("%d" , &timeLeft);
        memset(cost , 0 , n + n);
        memset(stay, 0 , sizeof(stay));
        timeLeft *= 60;//剩余时间
        for(int i = 1 ; i <= n ; ++i){
            scanf("%d" , &fish[i]);//输入渔获数量
        }
        for(int i = 1 ; i <= n ; ++i){
            scanf("%d" , &decr[i]);//输入减少数量
        }
        for(int i = 1 ; i < n ; ++i){
            scanf("%d" , &cost[i]);//输入数量
            cost[i] *= 5;//打表
        }
        //到哪个地方的费用,到时候O(1)提取
        for(int i = 1 ; i <= n ; ++i){
            cost[i] += cost[i - 1];
        }
        int ans = solve();
        printf("%d", stay[1]);
        for(int i = 2 ; i <= n ; ++i ){
            printf(", %d", stay[i]);
        }
        puts("");//换行
        printf("Number of fish expected: %d\n", ans);
        puts("");//记住这里还有个空行
    }
    return 0;
}
发布了69 篇原创文章 · 获赞 1 · 访问量 3057

猜你喜欢

转载自blog.csdn.net/Stagflation/article/details/101339539