Day4 備戰CCF-CSP練習

她说戴了不算給發表於2024-10-11

題目描述

有若干個任務需要在一臺機器上執行。

它們之間沒有依賴關係,因此可以被按照任意順序執行。

該機器有兩個 CPU 和一個 GPU

對於每個任務,你可以為它分配不同的硬體資源:

在單個 CPU 上執行。
在兩個 CPU 上同時執行。
在單個 CPUGPU 上同時執行。
在兩個 CPUGPU 上同時執行。
一個任務開始執行以後,將會獨佔它所用到的所有硬體資源,不得中斷,直到執行結束為止。

\(i\) 個任務用單個 CPU,兩個 CPU,單個 CPUGPU,兩個 CPUGPU 執行所消耗的時間分別為 \(a_i,b_i,c_i\)\(d_i\)

現在需要你計算出至少需要花多少時間可以把所有給定的任務完成。

輸入格式

輸入的第一行只有一個正整數 \(n\),是總共需要執行的任務個數。

接下來的 \(n\) 行每行有四個正整數 \(a_i,b_i,c_i,d_i\),以空格隔開。

輸出格式

輸出只有一個整數,即完成給定的所有任務所需的最少時間。

資料範圍

\(1≤n≤40,1≤a_i,b_i,c_i,d_i≤10\)

輸入樣例:

3
4 4 2 2
7 4 7 4
3 3 3 3

輸出樣例:

7

樣例解釋

有很多種排程方案可以在 \(7\) 個時間單位裡完成給定的三個任務,以下是其中的一種方案:

同時執行第一個任務(單 CPU 加上 GPU)和第三個任務(單 CPU),它們分別在時刻 \(2\) 和時刻 \(3\) 完成。

在時刻 \(3\) 開始雙 CPU 執行任務 \(2\),在時刻 \(7\) 完成。

題目分析

\(dp\)
思路尚不正確,有待最佳化
\(dp(i , j , k)\) 表示CPU1時間為\(i\)CPU2時間為\(j\)GPU時間為\(k\)的完成任務個數

C++程式碼

60分

#include <bits/stdc++.h>

using namespace std;

const int N = 50 , M = 220;

int n , m;
int a[N] , b[N] , c[N] , d[N];
int dp[M][M][M];

int main()
{
    cin >> n;
    int m1 = 0 , m2 = 0;
    for(int i = 1 ; i <= n; i ++)
    {
        cin >> a[i] >> b[i] >> c[i] >> d[i];
        if(i % 2) m2 += a[i];
        else m1 += a[i];
    }
    
    m = max(m1 , m2);
    
    for(int i = 1 ; i <= n ; i ++)
        for(int j = m ; j >= 0 ; j --)
            for(int k = m ; k >= 0 ; k --)
                for(int l = m ; l >= max(j , k) ; l --)
                {
                    // CPU1
                    if(j >= a[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - a[i]][k][l] + 1);
                    // CPU2
                    if(k >= a[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j][k - a[i]][l] + 1);
                    // CPU1 + CPU2
                    if(j >= b[i] && k >= b[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - b[i]][k - b[i]][l] + 1);
                    // CPU1 + GPU
                    if(j >= c[i] && l >= c[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - c[i]][k][l - c[i]] + 1);
                    // CPU2 + GPU
                    if(k >= c[i] && l >= c[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j][k - c[i]][l - c[i]] + 1);
                    // CPU1 + CPU2 + GPU
                    if(k >= d[i] && l >= d[i] && j >= d[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - d[i]][k - d[i]][l - d[i]] + 1);
                }
    
    int res = m;
    
    for(int j = 0 ; j <= m ; j ++)
        for(int k = 0 ; k <= m ; k ++)
            for(int l = 0 ; l <= m ; l ++)
                if(dp[j][k][l] == n)
                    res = min(res , max(j , max(k , l)));
                        
    
    cout << res << '\n';
    return 0;
}

50分

#include <bits/stdc++.h>

using namespace std;

const int N = 50 , M = 210;

int n , m;
int a[N] , b[N] , c[N] , d[N];
int dp[M][M][M];

int main()
{
    cin >> n;
    for(int i = 1 ; i <= n; i ++)
    {
        cin >> a[i] >> b[i] >> c[i] >> d[i];
        m += a[i];
    }
    
    m /= 2;
    
    for(int i = 1 ; i <= n ; i ++)
        for(int j = m ; j >= 0 ; j --)
            for(int k = m ; k >= 0 ; k --)
                for(int l = max(j , k) ; l >= 0 ; l --)
                {
                    // CPU1
                    if(j >= a[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - a[i]][k][l] + 1);
                    // CPU2
                    if(k >= a[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j][k - a[i]][l] + 1);
                    // CPU1 + CPU2
                    if(j == k && j >= b[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - b[i]][k - b[i]][l] + 1);
                    // CPU1 + GPU
                    if(j == l && j >= c[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - c[i]][k][l - c[i]] + 1);
                    // CPU2 + GPU
                    if(k == l && k >= c[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j][k - c[i]][l - c[i]] + 1);
                    // CPU1 + CPU2 + GPU
                    if(k == l && j == k && k >= d[i]) dp[j][k][l] = max(dp[j][k][l] , dp[j - d[i]][k - d[i]][l - d[i]] + 1);
                }
    
    int res = m;
    
    for(int j = 0 ; j <= m ; j ++)
        for(int k = 0 ; k <= m ; k ++)
            for(int l = 0 ; l <= m ; l ++)
                if(dp[j][k][l] == n)
                    res = min(res , max(j , max(k , l)));
                        
    
    cout << res << '\n';
    return 0;
}

相關文章