金明的預算方案加選課(樹上的揹包)
【模擬試題】選課 |
Time Limit:10000MS Memory Limit:65536K
Total Submit:365 Accepted:166
Case Time Limit:1000MS
Description
在大學裡每個學生,為了達到一定的學分,必須從很多課程裡選擇一些課程來學習,在課程裡有些課程必須在某些課程之前學習,如高等數學總是在其它課程之前 學習。現在有N門功課,每門課有個學分,每門課有一門或沒有直接先修課(若課程a是課程b的先修課即只有學完了課程a,才能學習課程b)。一個學生要從這 些課程裡選擇M門課程學習,問他能獲得的最大學分是多少?
Input
第一行有兩個整數N,M
接下來的N行,第I+1行包含兩個整數ki和si, ki表示第I門課的直接先修課,si表示第I門課的學分。若ki=0表示沒有直接先修課(1<=ki<=N, 1<=si<=20)。
Output
只有一行,選M門課程的最大得分。
Sample Input
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
Sample Output
13
Source
xinyue
題意:你要在n門課中選出m門,使得獲得的學分最大,當然有的課依賴於別的課先選。。。
分析:很容易想到在樹上揹包來解決問題,假設f[i][j]為以i為根的子樹,包括i,選擇j門課的最大值
那麼有f[i][j]=max{ f[i][a]+f[k][b] }k是i的子樹,a+b=j
這樣的複雜度是O(n*m^2)對於這題的資料範圍來說還是夠用的,不過我用上了對這種泛化物品的揹包的一種優化
複雜度降為O(n*m)
【AC程式碼】
#include <bits/stdc++.h> using namespace std; const int maxn = 302; int dp[maxn][maxn],k[maxn],s[maxn]; int n,m; void Tree_dp(int root,int c) { if(c){ for(int i=1; i<=n; i++){ if(k[i]==root){ for(int j=0; j<c; j++)//最多選j門課 dp[i][j] = dp[root][j] + s[i]; Tree_dp(i,c-1); for(int j=1; j<=c; j++){ dp[root][j] = max(dp[root][j],dp[i][j-1]); } } } } } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=1; i<=n; i++)scanf("%d%d",&k[i],&s[i]); //init. for(int i=1; i<=m; i++) dp[0][i] = 0; Tree_dp(0,m); printf("%d\n",dp[0][m]); } return 0; }
【金明的預算方案】
和上題一樣,同屬於有依賴性的揹包問題,這裡才用樹形dp+泛化物品的方法解決這個問題!
#include <bits/stdc++.h>
using namespace std;
const int maxn = 32002;
int dp[62][maxn],v[maxn],p[maxn],q[maxn];
int n,m;
void Tree_dfs(int root,int c)
{
if(c)
{
for(int i=1; i<=n; i++){
if(q[i]==root){
for(int j=0; j<=c-v[i]; j++){
dp[i][j] = dp[root][j] + p[i]*v[i];
}
Tree_dfs(i,c-v[i]);
for(int j=v[i]; j<=c; j++){
dp[root][j] = max(dp[root][j],dp[i][j-v[i]]);
}
}
else
continue;
}
}
}
int main()
{
while(~scanf("%d%d",&m,&n))
{
for(int i=1; i<=n; i++) scanf("%d%d%d",&v[i],&p[i],&q[i]);
for(int i=1; i<=m; i++) dp[0][i] = 0;
Tree_dfs(0,m);
printf("%d\n",dp[0][m]);
}
return 0;
}
相關推薦
金明的預算方案加選課(樹上的揹包)
【模擬試題】選課 Time Limit:10000MS Memory Limit:65536K Total Submit:365 Accepted:166 Case Time Limit:1000MS Description 在大學裡每個學生,為了達到一定的
【洛谷1273】有線電視網(樹上揹包)
點此看題面 大致題意: 給你一棵帶權樹,已知每連線一條邊需要一定花費,如果某個葉節點能到達根,可以獲得一定收益。問在不虧本的情況下,最多能使多少個葉節點能到達根。 樹上揹包 這是一道比較經典的樹上揹包
hdu1561、The more, The Better(樹上揹包)
The more, The Better Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9999 Acc
51nod_1490: 多重遊戲(樹上博弈)
== names lin its code bit 都是 namespace 51nod 題目鏈接 該題實質上是一個樹上博弈的問題。要定義四種狀態——2先手必勝 1先手必敗 3可輸可贏 0不能控制 葉子結點為先手必勝態; 若某結點的所有兒子都是先手必敗態,則該結點為先手必
光貓手機自動激活系統-開發指南-004- OLT添加vlan(ADD- VLAN)
手機 光貓 手機激活系統 -開發指南-004- olt添加vlan(add- vlan) ADD-VLAN::OLTID=10.124.202.199:CTAG::VLAN=2108,DESC=2108,VLANMODE=SINGLE,PORTLIST=NA-0-19-0|NA-0-20-0|
ARC078 D.Fennec VS. Snuke(樹上博弈)
turn 路徑 std oid 最大 main 沒有 次數 cto 題目大意: 給定一棵n個結點的樹 一開始黑方占據1號結點,白方占據n號結點 其他結點都沒有顏色 每次黑方可以選擇黑色結點臨近的未染色結點,染成黑色 白方同理。 最後誰不能走誰輸。 題解: 其實簡單想想就
Redis的集群方案之Sentinel(哨兵模式)(待實踐)
tps log csdn mooc 實現 tail net sentinel .net 哨兵模式是主從切換的一種方案,但是可以借助此方案實現集群,達到高可用。 先收集教程,待實踐。 參考: https://redis.io/topics/sentinel(官方文
vue和mintui-Loadmore結合實現下拉刷新,上拉加載 (待優化)
res 延遲 設置 body 轉換 ext over 開發 體驗 mintui是餓了麽團隊針對vue開發的移動端組件庫,方便實現移動端的一些功能,這裏只用了Loadmore功能實現移動端的上拉分頁刷新,下拉加載數據.mintui官網:http://mint-ui.githu
vue組件重新加載(刷新)
自己 組件 vue組件 自己的 AI exp vue ace div vue組件重新加載(刷新) 第一種方法:利用v-if控制router-view,在根組件APP.vue中實現一個刷新方法 <template> <router-view v-i
hdu6223 Infinite Fraction Path 2017沈陽區域賽G題 bfs加剪枝(好題)
getc 細節 \n ret ast scrip mat tom ide 題目傳送門 題目大意:給出n座城市,每個城市都有一個0到9的val,城市的編號是從0到n-1,從i位置出發,只能走到(i*i+1)%n這個位置,從任意起點開始,每走一步都會得到一個數字,走n-1步,會
ceph添加osd(ceph-deploy)
配置文件 秘鑰 之一 alt udev dep 修改主機名 ceph host 修改主機名和 /etc/hosts 關閉防火墻和 SELINUX 安裝和配置 NTP ceph-deploy 節點安裝 安裝 ceph-deploy sudo yum install ceph-
PAT-乙-1074 1074 宇宙無敵加法器 (20 分)
程式碼 #include <iostream> using namespace std; int main() { string s, s1, s2; cin>>s>>s1>>s2; while(s1.length()
洛谷-P2014 選課(樹形DP)
題意 n n n 門功課形成一棵樹,每門課有一個學分,選 m m m 門,選擇一門課的前提是選擇它的父親,求最大學分。
FJUT 聰明的商人(樹上倍增)題解
思路:求樹上兩點的距離,顯然是dep[u] + dep[v] - 2 * dep[lca],用樹上倍增去寫。 參考:樹上倍增的寫法和應用(詳細講解,新手秒懂) 程式碼: #include<set> #include<map> #include<stack> #i
BZOJ4753: [Jsoi2016]最佳團體(分數規劃+樹上揹包)
BZOJ4753: [Jsoi2016]最佳團體(分數規劃+樹上揹包) 標籤:題解 閱讀體驗 BZOJ題目連結 洛谷題目連結 具體實現 看到分數和最值,考慮分數規劃 我們要求的是一個\(\dfrac{\sum P_i}{\sum S_i}\)最大對吧,考慮二分一個答案\(mid\) 那麼就會有合法條件\
[LeetCode]66. 加一(Plus One)Java
一、題目: LeetCode地址 給定一個由整數組成的非空陣列所表示的非負整數,在該數的基礎上加一。 最高位數字存放在陣列的首位, 陣列中每個元素只儲存一個數字。 你可以假設除了整數 0 之外,這個整數不會以零開頭。 示例 1: 輸入: [1,2,3] 輸出:
給影象加噪聲(椒鹽噪聲)
原理:隨機的將影象某些畫素值改為0或255 新增椒鹽噪聲 def SaltAndPepper(src,percetage): SP_NoiseImg=src SP_NoiseNum=int(percetage*src.shape[0]*src.shape[1]) for i
牛客網 272B Xor Path(樹上操作)
題目連結:Xor Path 題意:每個頂點的點權為Ai,任意兩點路徑上點權異或和為Path(i,j),求所有Path(i,j)和。 題解:考慮每個頂點被用到的次數,分以下三種情況: 1.本身和其他頂點:n-1 2.該頂點上面的頂點(k)和下面的頂點(m)通過該點進行連線:k*m 3.該頂底下面的頂點
PAT乙級 1074 宇宙無敵加法器 (20 分)
地球人習慣使用十進位制數,並且預設一個數字的每一位都是十進位制的。而在 PAT 星人開掛的世界裡,每個數字的每一位都是不同進位制的,這種神奇的數字稱為“PAT數”。每個 PAT 星人都必須熟記各位數字的進製表,例如“……0527”就表示最低位是 7 進位制數、第 2 位是 2 進位制數、第
【Android】_UI設計_學生註冊、選課(無資料庫)
學生管理系統 (一) 效果實現圖 (二) 專案結構圖 (三) 具體的編碼實現 (1)註冊 (2)註冊 (3)配置檔案 (一) 效果實現圖 目標:通過一個SQLite的資料庫的操作實現學