年會 (記憶化搜尋+二叉樹思想)-------------------------------------C語言——菜鳥級
時間限制: 1Sec 記憶體限制: 128MB 提交: 54 解決: 24
題目描述
背景
某大學校長準備開一次年會. 該校的員工具有等級結構, 即師生關係構成一棵樹, 以校長為樹根. 員工號是1到N之間的整數. 人事部門把所有員工按活躍度排序. 為了讓年會使所有參加者都玩的高興, 校長不想讓任何一個員工和他/她的直接導師同時被邀請.
你的任務是列一張客人名單, 以使客人活躍度最大.
輸入
第1行是一個整數N. 1 ≤ N ≤ 6000.
接著的N行包含相應員工的活躍度.活躍度是一個-128到127之間的整數.
其後是師生關係表. 每行有如下形式:
L K
表示第K個員工是第L個的直接導師.
輸入以
0 0
結束.
輸出
輸出是客人最大總活躍度.
樣例輸入
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
樣例輸出
5
//思路: 記憶化搜尋 + 二叉樹
//常理來說大學裡 一個導師可以有多個學員 但一個學員只能有一個導師(二叉樹)
// 導師和學員不能同時邀請,那就是除了同時邀請外 還有三種情況,邀導不邀學
//邀學不邀導 和都不邀 (0與1 )的關係 通過DFS列舉各類情況,優化記憶陣列;
#include <string.h>
#include <stdio.h>
#define M 6002
#define max(a,b) a>b?a:b
int n;
int v[M];
int bj[M];
//標記非根節點(將有學員身份的員工或者學員標記)
//沒標記的就只有導師身份(即根節點)
int ds[M][15];
//導師陣列 ds[i][j]=4;代表第i個人作為導師身份時第j個學員為4號學員
int dp[M][2];//記憶陣列dp[L][0]代表滿足條件下該員工(L)的導師未邀請狀態最優活躍度
// dp[L][1]代表滿足條件下該員工(L)的導師邀請狀態下最優活躍度
int dfs(int L,int last)
{ //優化 記憶陣列
if(dp[L][last]!=-1)return dp[L][last];
if (!ds[L][0])//表示 當前員工無學員 即 該員工只有學員身份
{ if(last==0&&v[L]>0)return v[L];//若該員工的導師未邀請且該學員可i活躍氣氛
else return 0;//不活躍當然不能要;
}
int ans1=0, ans2=0,i;
//若不邀請該員工 就去找該員工的學員(下一層節點)的最優解
i=0;while(ds[L][i]!=0)ans1+=dfs(ds[L][i],0),i++;
//若該員工的導師沒被邀請 並且邀請該員工 然後去找該員工的學員(下一層節點)的最優解
if(last!=1)i=0;while(ds[L][i]!=0)ans2+=dfs(ds[L][i],1),i++;
if(last==0)//若該員工的導師未邀請
{dp[L][0]=max(ans1,ans2+v[L]);
//該節點的最優解為(邀請該員工 與不邀請的該員工的)最大值
//(即可能 該員工和他導師活躍值為負 都不邀請滴好)
return dp[L][0];
}//若該員工的導師邀請 ,那該員工只能不邀請
dp[L][1]=ans1;
return dp[L][1];
}
int main()
{ int i,l,k,j,ans=0;
scanf("%d",&n);
memset(bj,0, sizeof(bj));
memset(ds,0, sizeof(ds));
memset(dp,-1,sizeof(dp));
for(i=1;i<=n;i++)
scanf("%d",&v[i]);
while(1)
{
scanf("%d%d",&l,&k);
if(l==0&&k==0)break;
j=0;
while(ds[k][j]!=0)j++;//給l學員在他導師那找個序號位置
ds[k][j]=l;
bj[l]=1;//標記該員工有學員身份
}
for(i=1;i<=n;i++)//列舉根節點( 只有導師身份的人)
if(!bj[i])ans+=dfs(i,0);//把各各沒有關係的導師集合的最優解加起來
printf("%d\n",ans);
return 0;
}
相關推薦
年會 (記憶化搜尋+二叉樹思想)-------------------------------------C語言——菜鳥級
時間限制: 1Sec 記憶體限制: 128MB 提交: 54 解決: 24 題目描述 背景 某大學校長準備開一次年會. 該校的員工具有等級結構, 即師生關係構成一棵樹, 以校長為樹根. 員工號是
經典動態規劃 導彈攔截(簡單)---------C語言——菜鳥級
/*題目描述 某國為了防禦敵國的導彈襲擊,發展中一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於等於前一發的高度。某天,雷達捕捉到敵國導彈來襲。由於該系統還在試用階段,所以只用一套系統,因此有可能不能攔截所有的導彈。
藍橋杯 歷屆試題 帶分數(全排)----------------------C語言——菜鳥級
/*問題描述 100 可以表示為帶分數的形式:100 = 3 + 69258 / 714。 還可以表示為:100 = 82 + 3546 / 197。 注意特徵:帶分數中,數字1~9分別出現且只出
經典動態規劃 導彈攔截(簡單)-----------------------------C語言——菜鳥級
/*題目描述 某國為了防禦敵國的導彈襲擊,發展中一種導彈攔截系統。但是這種導彈攔截系統有一個缺陷:雖然它的第一發炮彈能夠到達任意的高度,但是以後每一發炮彈都不能高於等於前一發的高度。某天,雷達捕捉到敵國導彈來襲。由於該系統還在試用階段,所以只用一套系統,因此有
A. Help Vasilisa the Wise 2 (邏輯)-----------------------C語言——菜鳥級
A. Help Vasilisa the Wise 2 time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard
明明隨機數(簡單位操作)-------------------------------C語言——菜鳥級
問題 1102: 明明的隨機數 時間限制: 1Sec 記憶體限制: 128MB 提交: 512 解決: 183 題目描述 明明想在學校中請一些同學一起做一項問卷調查,為了實驗的客觀性,他先用計算機生成了N個1到1000之間的隨機整數(N≤100),對於其中
藍橋杯 演算法訓練 金陵十三釵(dp+狀態壓縮) ----------------------------C語言——菜鳥級
/*問題描述 在電影《金陵十三釵》中有十二個秦淮河的女人要自我犧牲代替十二個女學生去赴日本人 的死亡宴會。為了不讓日本人發現,自然需要一番喬裝打扮。但由於天生材質的原因, 每個人和每個人之間的相似度是不同的。由於我們這是程式設計題,因此情況就變成了金陵
藍橋杯 名次判斷(詳解)--------------------------C語言——菜鳥級
/*問題描述 某場比賽過後,你想要知道A~E五個人的排名是什麼,於是要求他們每個人說了一句話。 (經典的開頭……-_-!)得了第1名的人23,說了假話;得了第5名的人不好意思,也說了假話; 為了使求解問題簡單,第3名同樣說了假話。(奇數名次說假話)
第八十六題(搜尋二叉樹建立)
如何編寫一個程式,把一個有序整數陣列放到二叉樹中? 分析:為了讓搜尋二叉樹的查詢等操作接近於O(log(n))。我們以有序陣列的中間位置的數字作為搜尋二叉樹的根節點,以其左半部分資料建立搜尋二叉樹作為根節點的左子樹。以其有半部分資料建立搜尋二叉樹作為根節點的右子樹。這是一個遞
Twenty Questions(記憶化搜尋,狀態壓縮dp)
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #inclu
[leetcode]Same Tree(判斷兩個二叉樹是否相等 C語言實現)
Same Tree Given two binary trees, write a function to check if they are equal or not. Two binary trees are considered equal if th
求二叉樹的寬度C語言版
/*層次遍歷二叉樹,每一層遍歷完成以後都重新插入特定的指標(比如本例使用的特殊指標是資料元素為#,左右兒子為空的指標),這樣在每次訪問到所指向資料為#的佇列中的結點指標是就知道該指標是這層的末尾,需要
二叉樹結點深度(C語言)
在每個結點中儲存其深度。在二叉樹的建立和遍歷過程中可以發現,每次呼叫函式的時候都是前往左子樹或者右子樹,這個時候所前往的結點的深度都會增加一個,而當函式呼叫完成的時候會退出函式棧在此函式中的結點深度就會減少一個。因此可以設定一個全域性變數deep來表示當前函式中的結點的深
二叉樹的操作--C語言實現
div break 叠代 二叉樹 node 若是 postorder 元素 初始化 樹是一種比較復雜的數據結構,它的操作也比較多。常用的有二叉樹的創建,遍歷,線索化,線索化二叉樹的遍歷,這些操作又可以分為前序,中序和後序。其中,二叉樹的操作有遞歸與叠代兩種方式,鑒於我個人的
平衡二叉樹的建立 c語言範例
#include <stdio.h> #include <stdlib.h> #include <s
pat(甲)1064--(搜尋二叉樹+滿二叉樹)
1064 Complete Binary Search Tree (30 分) A Binary Search Tree (BST) is recursively defined as a binary tree which has the following proper
一個簡單的英語到漢語的翻譯過程(搜尋二叉樹)
英語到漢語的翻譯: 原理:在我看來,既可以運用陣列,也可以運用搜索二叉樹,或者是其它任意一種儲存結構應該都可以完成這個操作,但應用搜索二叉樹,效率會更高,因為每一次搜尋,就會排除許多無用的資料。 例如,在上圖中查詢1,只需要通過上圖的3次比較就可以得出結果,每
LeetCode刷題-98——Validate Binary Search Tree(驗證搜尋二叉樹)
連結:題目:給定一個二叉樹,判斷其是否是一個有效的二叉搜尋樹。一個二叉搜尋樹具有如下特徵:節點的左子樹只包含小於當前節點的數。節點的右子樹只包含大於當前節點的數。所有左子樹和右子樹自身必須也是二叉搜尋樹
建立完全搜尋二叉樹(Complete Binary Search Tree )(c++)
Complete Binary Search Tree(c++) 因為題目要求,首先輸入二叉樹的結點個數,再輸入每個結點對應的值,建立二叉樹,既是二叉搜尋樹,又是完全二叉樹。 整體思路 根據輸入的結點數,建立完全二叉樹; 將節點數值放在陣列中,從小到大排序;
二叉搜尋樹(搜尋二叉樹)轉換成一個雙向連結串列
1.題目描述: 將一個二叉搜尋樹轉換成一個雙向連結串列; 2.二叉搜尋樹,直接看圖: 如圖就是一個二叉搜尋樹的模型,也就是轉換函式的入口資料,也是下邊函式中即將用到的例子,既然有輸入,肯定有輸出,先面在看一張圖(第三條): 3.輸入輸出模型: 右邊就是最終的輸出結果,5