首页 > 其他分享 >【题目】LuoguP1065

【题目】LuoguP1065

时间:2024-02-28 09:47:27浏览次数:20  
标签:cnt 题目 bsy LuoguP1065 int fr nowmac MAXN

准备机试,做两道题复健(这事我是不是干了好多次了)。

https://www.luogu.com.cn/problem/P1065

题意是有n个工件,每个工件有m道工序,每个工件的每道工序有其用时,同时对应一台机器,机器总共也有m台。每台机器同时只能处理一个工序。现给出工件的工序顺序,问尽可能靠前安排,所用的时间。

 

一种显然的做法是把时间像桶一样存起来,每安排一个工序就把一个区间格式化为占用。然后每次从开头开始查找。

但是要我说,这么做能过是因为数据不给力。比如,如果某工序需要2^31-1时间的话就不行了。

注意到工件和工序数量相对较少,所以可以用存区间+排序的方法做。具体思路是,对于每台机器创建一个区间列表来表示占用了的区间,添加新区间时就查找区间之间的间隔是否有足够大的,如果有就靠前插入。另外由于同一个工件的工序有前后之分,所以还需要一个数组来记录上一个工序的最后完成时间,和查找范围的左侧取最值。

一个小trick是存储区间的时候在头和尾多存储两个,头的右边界是0,尾的左边界是无穷,这样不需要额外的边界判断逻辑。

AC代码:

#include <iostream>
#include <cstdio>
#include <utility>
#include <algorithm>

#define fr first 
#define se second  

using namespace std;

const int MAXN = 22;//product
const int MAXM = 22;//process

pair<int,int> info[MAXN][MAXM];//machine, time use 

int order[MAXN*MAXM];
int m,n;

int lastpos[MAXN];
int step[MAXN];
pair<int,int> bsy[MAXM][MAXN*MAXM];
int cnt[MAXM];
int ntime;

bool cmp(pair<int,int> a, pair<int,int> b){
    return a.fr < b.fr;
}

int _max(int a,int b){
    return a>b?a:b;
}


int main(){
    //freopen("./p1065.in","r",stdin);
    //freopen("./p1065.out","w",stdout);


    cin>>m>>n;
    for(int i = 1; i <= n*m ; i++)
        cin>>order[i];
    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m ; j++)
            cin>>info[i][j].first;

    for(int i = 1; i <= n; i ++)
        for(int j = 1; j <= m ; j++)
            cin>>info[i][j].second;

    for(int i = 1; i <= m ; i++){
        bsy[i][1].fr = 0x7fffff;
        cnt[i] = 1;
    }
    
    int mx = 0;

    for(int iii = 1; iii <= n*m ; iii++){
        int nowpro = order[iii];
        int nowstep = step[nowpro]+1;
        int nowmac = info[nowpro][nowstep].fr;
        int nowtime = info[nowpro][nowstep].se;
        
        for(int i = 1; i <= cnt[nowmac]; i++){
            int rig = _max(bsy[nowmac][i-1].se, lastpos[nowpro]);
            if(bsy[nowmac][i].fr - rig - 1 >= nowtime){
                bsy[nowmac][cnt[nowmac]].fr = rig + 1;
                bsy[nowmac][cnt[nowmac]].se = rig + nowtime;
                lastpos[nowpro] = bsy[nowmac][cnt[nowmac]].se;
                //printf("新的%d的最后位置为%d \n",nowpro, lastpos[nowpro]);
                if(bsy[nowmac][cnt[nowmac]].se > mx) mx = bsy[nowmac][cnt[nowmac]].se;
                //printf("add:machine:%d,product:%d,count:%d,%d-%d\n",nowmac,nowpro,cnt[nowmac],bsy[nowmac][cnt[nowmac]].fr,bsy[nowmac][cnt[nowmac]].se);
                bsy[nowmac][++cnt[nowmac]].fr = 0x7fffff;
                step[nowpro] ++;
                break;
            }
        }

        sort(bsy[nowmac]+1, bsy[nowmac] + cnt[nowmac], cmp);

    }
    
    cout<<mx<<endl;

    return 0;
}
View Code

 

标签:cnt,题目,bsy,LuoguP1065,int,fr,nowmac,MAXN
From: https://www.cnblogs.com/dudujerry/p/18038984

相关文章

  • 经典算法题目-动态规划
    动态规划动归五部曲一、确定dp数组以及下标的含义二、确定递推公式三、dp数组进行初始化四、确定遍历顺序五、举例推导dp数组746.使用最小花费爬楼梯解决思路定义dp[i]为爬到第i个台阶的最低花费递推公式。因为每一次能爬一步或两步,dp[i]为前面的两格走两步过来或......
  • 题目总结
    CF559C-GeraldandGiantChess一道数学+DP的\(\color{#3498DB}\texttt{提高+/省选-}\)题。题目要求求从\((1,1)\)点到\((h,w)\)点不经过黑色方格的路径数。解题思路观察数据范围,可以发现数据范围大概率与\(n\)有关。首先,不考虑黑色方格,易发现路径数为\(\math......
  • HydroOJ 从入门到入土(14)批量修改题目难度
    老师,这排名咋算的?为啥我在他后边??很多学生比较关注排名,而排名又受到各种因素影响,其中最不可控的是题目难度(源码)。因为题目难度默认为0,也就是自动计算,但自动计算题目难度的时候,是从10倒数的,AC率高了才会逐渐下降,但也基本不太会降到1。而手动定过难度的题目,基本都从1开始......
  • 数学题目合集
    翻转性质:如果翻转的区间所有数对个数为偶,则整个逆序对个数奇偶性不变;否则改变。证明:首先翻转区间外的逆序对个数不会变化,翻转区间与翻转区间外的逆序对个数也不会变化。假设翻转前翻转区间内有\(cnt\)个逆序对,则翻转后有\(len\times(len-1)/2-cnt\)个逆序对,差为\(len\tim......
  • dp 未分类题目
    2484.CountPalindromicSubsequencesGivenastringofdigits s,return thenumberof palindromicsubsequences of s havinglength 5.Sincetheanswermaybeverylarge,returnit modulo 109+7.Note:Astringis palindromic ifitreadsthes......
  • 一维动态规划题目
    746.使用最小花费爬楼梯力扣题目链接思路:暴力递归解题思路把每一种可能都枚举,也就是dfs搜索每一种可能的情况,再求出其中最小的花费返回即可。代码实现//求两个数中的最小值intmin(inta,intb){returna<b?a:b;}//表示从下标i开始到costSize-1位置的......
  • 其他题目合集
    袭击给出\(2n\)个点,求在前\(n\)个和后\(n\)个点中各选一个点的距离的最小值是多少。分治出处:《算法竞赛进阶指南》题解:先考虑只有一种点,怎么求两两距离的最小值。分治,整体的最小距离\(ans=\min(\)左半边的最小值,右半边的最小值,左右之间的最小值\().\)只需考虑左右之......
  • 动态规划题目合集
    3n多米诺问题\(dp[i]\)表示前\(i\)列的方案数,\(dp2[i]\)表示前\(i\)列但是最上面一行缺一个的方案数。\(dp[i],dp2[i]\)可以相互递推,而且刚好是矩阵递推。矩阵快速幂优化。Walk有向无权图。求长度\(k\)的路径条数。我们发现邻接矩阵的\(k\)次方各个元素求和就是......
  • 图论题目合集
    题面:要求把\(1\simn\)排序,满足给定的所有条件,满足条件之后,编号越小要越靠前。(满足条件情况下,先让1最靠左,然后让2……)每个条件会给出两个数\(a,b\),表示\(a\)必须在\(b\)之前。解答:看起来很像拓扑排序。于是我们对于每个条件\(a,b\),从\(a\)向\(b\)连一条边。每......
  • 贪心题目合集
    磁带存储:有\(n\)个磁带,每个片段有两个参数:时长\(t_i\)和频率\(a_i\)。以某种顺序把片段排在磁带里,每个片段的花费为(播放完这个片段的时刻)乘以(该片段的频率)求最小花费和。因为两个片段交换,对之后没有影响。所以可以考虑一个顺序中,如果\(x,x+1\)片段换位置后花费的变化。......