Vijos P1180選課 解題報告

2021-06-22 20:00:42 字數 1788 閱讀 4235

學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了n(n<300)門的選修課程,每個學生可選課程的數量m是給定的。學生選修了這m門課並考核通過就能獲得相應的學分。

在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其它的一些課程的基礎上才能選修。例如《frontpage》必須在選修了《windows操作基礎》之後才能選修。我們稱《windows操作基礎》是《frontpage》的先修課。每門課的直接先修課最多只有一門。兩門課也可能存在相同的先修課。每門課都有乙個課號,依次為1,2,3,…。 例如:

表中1是2的先修課,2是3、4的先修課。如果要選3,那麼1和2都一定已被選修過。   你的任務是為自己確定乙個選課方案,使得你能得到的學分最多,並且必須滿足先修課優先的原則。假定課程之間不存在時間上的衝突。

輸入檔案的第一行包括兩個整數n、m(中間用乙個空格隔開)其中1≤n≤300,1≤m≤n。

以下n行每行代表一門課。課號依次為1,2,…,n。每行有兩個數(用乙個空格隔開),第乙個數為這門課先修課的課號(若不存在先修課則該項為0),第二個數為這門課的學分。學分是不超過10的正整數。

輸出檔案每行只有乙個數。第一行是實際所選課程的學分總數。

我的思路:

1.由於選課強調要選一門課就必須要選它的先選課.因此可以考慮用書來儲存如果i的先選課是j,那麼將i作為j的孩子節點此處用孩子兄弟表示法來表示這棵樹,由於題目所屬可能不止一棵樹,為了方便處理,將他們作為編號為零的節點的子樹,(置0這棵樹選課學分為零,且選擇它時

也不消耗選課數目)

2記dp[i][j]為從節點i,還有j個選課名額時所能得到的最大學分。

3.當j==0,或者i,編號不存在時選課學分為零.

4.選擇i,還有j個名額時的決策總共是

選擇i的孩子課程分配k個名額,與選擇i的兄弟課程分配m-(k+1)個名額 + 選擇i課程的學分.(由於要選擇i的子課程是必須選i課程,因此多分配乙個)

與只選擇,兄弟課程的最大值 dp[nbother[no],m]的最大值。

//vijos 1180 選課. 

#include #include #define maxn 505

int fchild[maxn]=;

int nbrother[maxn]=;

int score[maxn]=;

int dp[maxn][maxn];

int count=1;

void insertbrother(int no,int i)

nbrother[no]=i;

}int max(int a,int b)

void insert(int no,int i)else

}void print(int no)

}int slove(int no,int m)else

dp[no][m]=max(dp[no][m],s);

} return dp[no][m];

} }

int main()

printf("%d",slove(0,m+1));

return 0;

}

11 8 刪除結點

刪除結點 輸入若干個正整數 輸入 1為結束標誌 建立乙個單向鍊錶,再輸入乙個整數m,刪除鍊錶中值為m的所有結點。試編寫相應程式。鍊錶結點定義 struct listnode 函式介面定義 struct listnode readlist struct listnode deletem struct ...

118 合併區間

題目描述 給出乙個區間的集合,請合併所有重疊的區間。示例 1 輸入 1,3 2,6 8,10 15,18 輸出 1,6 8,10 15,18 解釋 區間 1,3 和 2,6 重疊,將它們合併為 1,6 示例 2 輸入 1,4 4,5 輸出 1,5 解釋 區間 1,4 和 4,5 可被視為重疊區間。c...

11 8 學習記錄

下拉列表彈出方向預設為向下,當然我們也可以設定不同的方向。如果你希望下拉列表向右下方彈出,可以在 div 元素上新增 dropdown menu end 類 下拉列表右下方彈出 button 鏈結 1a li 鏈結 2a li 鏈結 3a li ul div 嘗試一下 如果你希望上拉選單向上彈出,可...