就决定是你了!
題目來源:https://biancheng.love/contest-ng/index.html#/34/problems
題目描述
Nova君來到神奇寶貝中心,準(zhǔn)備從存儲機(jī)中挑選若干個Pockmon去挑戰(zhàn)最后的四天王和聯(lián)盟冠軍。Nova君現(xiàn)在有N只可挑選的Pockmon,對于第 i 只Pockmon,他的體總為 wi ,戰(zhàn)斗力為 vi 。現(xiàn)在聯(lián)盟規(guī)定,只能攜帶總重量為M的Pockmon進(jìn)行挑戰(zhàn)。那么,Nova君要怎么挑選才能使戰(zhàn)斗力最強(qiáng)呢?大家肯定會說,這不是個簡單的背包問題嘛?嗯,大概。但是現(xiàn)在有個問題,由于某些Pockmon在冒險的途中,和存儲機(jī)內(nèi)的其他Pockmon產(chǎn)生了羈絆,有可能對另一只Pokmon產(chǎn)生依賴,非得被依賴的那只被選中才能發(fā)揮戰(zhàn)斗力,否則只能是個戰(zhàn)斗力為0的賣萌生物而已,好在每只Pockmon都很專情,只會依賴一只(或者不依賴)。
PS:
(1) 依賴關(guān)系不對稱,即,若A依賴B,B不一定依賴A,俗稱beitai;
(2) 可能出現(xiàn)這樣的情況:A依賴B,B依賴C,C依賴A,俗稱love triangle,當(dāng)然也有可能是多邊形(悲傷臉)
(3) 保證不會出現(xiàn)自己依賴自己的情況
輸入
多組測試數(shù)據(jù)(組數(shù)不超過10),對于每組數(shù)據(jù),輸入4行,第一行是兩個正整數(shù)N,M,表示Pockmon總數(shù)和聯(lián)盟允許的最大重量,第二行包含N個正整數(shù)w1,w2...wn,表示第 i 個Pockmon的重量,第三行包含N個正整數(shù)v1,v2...vn,表示第 i 個Pockmon的戰(zhàn)斗力,第四行包含N個正整數(shù)D1,D2...Dn,表示第 i 個Pockmon依賴的Pockmon的序號,如果沒有依賴對象,則 Di=0。
PS:輸入數(shù)據(jù)都在INT范圍內(nèi)
輸出
對于每組數(shù)據(jù),輸出一行,表示戰(zhàn)斗力的最大值
輸入樣例
3 10 4 5 6 2 3 4 3 1 2 3 10 4 5 6 2 3 4 0 1 1輸出樣例
0 6代碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int e=505; 5 int n,m,tmpw=0,tmpn; 6 int w[e]= {0},v[e]= {0},b[e]= {0},c[e]= {0},f[e][5*e]= {0},d[e]= {0}; 7 bool mapp[e][e]= {0}; 8 9 void floride() 10 { 11 for(int i=1; i<=n; i++) //弗洛里德判斷是否有環(huán); 12 for(int j=1; j<=n; j++) 13 for(int k=1; k<=n; k++) 14 if(mapp[k][i]==1 && mapp[i][j]==1) 15 mapp[k][j]=1; 16 } 17 18 19 void merge()//合點 20 { 21 tmpn=n; 22 for(int i=1; i<=tmpn; i++) 23 for(int j=1; j<=tmpn; j++) 24 { 25 if(mapp[i][j]==1 && mapp[j][i]==1 && i!=j && w[i]>0 && w[j]>0)//如果是新環(huán); 26 { 27 tmpn++; 28 v[tmpn]=v[i]+v[j]; 29 w[tmpn]=w[i]+w[j]; 30 tmpw--; 31 w[i]=tmpw; 32 w[j]=tmpw; //tmpw+tmpn永遠(yuǎn)等于最開始的n 33 } 34 35 //如果j依賴的點被合并(是舊環(huán)),且j在環(huán)里 36 if(w[d[j]]<0 && w[j]>0 && mapp[j][d[j]]==1 && mapp[j][d[j]]==1) 37 { 38 w[n-w[d[j]]]+=w[j]; 39 v[n-w[d[j]]]+=v[j]; 40 w[j]=w[d[j]]; 41 } 42 43 //如果j依賴的點在環(huán)里,但是j不在環(huán)里 44 if(w[d[j]]<0 && w[j]>0) 45 if((mapp[j][d[j]]==1 && mapp[d[j]][j]==0) || (mapp[j][d[j]]==0 && mapp[d[j]][j]==1)) 46 d[j]=n-w[d[j]]; 47 } 48 } 49 50 int dfs(int x,int k) 51 { 52 if(f[x][k]>0) return(f[x][k]); 53 if(x==0 || k<=0) return(0); 54 //不取x 55 f[b[x]][k]=dfs(b[x],k); 56 f[x][k]=f[b[x]][k]; 57 int y=k-w[x]; 58 for(int i=0; i<=y; i++) 59 { 60 f[c[x]][y-i]=dfs(c[x],y-i); 61 f[b[x]][i]=dfs(b[x],i); 62 f[x][k]=max(f[x][k],v[x]+f[c[x]][y-i]+f[b[x]][i]); 63 } 64 return(f[x][k]); 65 } 66 67 68 69 int main() 70 { 71 while(cin>>n>>m) 72 { 73 tmpw=0; 74 memset(w,0,sizeof(w)); 75 memset(v,0,sizeof(v)); 76 memset(c,0,sizeof(c)); 77 memset(b,0,sizeof(b)); 78 memset(d,0,sizeof(d)); 79 memset(f,0,sizeof(f)); 80 memset(mapp,0,sizeof(mapp)); 81 82 for(int i=1; i<=n; i++) 83 scanf("%d",&w[i]); 84 for(int i=1; i<=n; i++) 85 scanf("%d",&v[i]); 86 for(int i=1; i<=n; i++) 87 { 88 int a; 89 scanf("%d",&a); 90 d[i]=a; 91 mapp[a][i]=1; 92 } 93 94 floride(); 95 merge(); 96 97 //多叉轉(zhuǎn)二叉 98 for(int i=1; i<=tmpn; i++) 99 if(w[i]>0) 100 { 101 b[i]=c[d[i]]; 102 c[d[i]]=i; 103 } 104 cout<<dfs(c[0],m)<<endl; 105 } 106 }
?
?轉(zhuǎn)載于:https://www.cnblogs.com/zpfbuaa/p/5037570.html
總結(jié)
- 上一篇: 硬盘坏道检测修复工具
- 下一篇: 领势MR9000X路由器关闭访客网络