洛谷 P2114 [NOI2014]起床困难综合症 解题报告
P2114 [NOI2014]起床困難綜合癥
題目描述
21世紀,許多人得了一種奇怪的病:起床困難綜合癥,其臨床表現為:起床難,起床后精神不佳。作為一名青春陽光好少年,atm一直堅持與起床困難綜合癥作斗爭。通過研究相關文獻,他找到了該病的發病原因: 在深邃的太平洋海底中,出現了一條名為drd的巨龍,它掌握著睡眠之精髓,能隨意延長大家的睡眠時間。 正是由于drd的活動,起床困難綜合癥愈演愈烈, 以驚人的速度在世界上傳播。為了徹底消滅這種病,atm決定前往海底,消滅這條惡龍。歷經千辛萬苦,atm終于來到了drd所在的地方,準備與其展開艱苦卓絕的戰斗。drd有著十分特殊的技能,他的防御戰線能夠使用一定的運算來改變他受到的傷害。具體說來,drd的防御戰線由n扇防御門組成。每扇防御門包括一個運算op和一個參數t,其中運算一定是OR,XOR,AND中的一種,參數則一定為非負整數。如果還未通過防御門時攻擊力為x,則其通過這扇防御門后攻擊力將變為x op t。最終drd受到的傷害為對方初始攻擊力x依次經過所有n扇防御門后轉變得到的攻擊力。
由于atm水平有限,他的初始攻擊力只能為0到m之間的一個整數(即他的初始攻擊力只能在 0, 1, … , m中任選,但在通過防御門之后的攻擊力不受m的限制)。為了節省體力,他希望通過選擇合適的初始攻擊力使得他的攻擊能讓drd受到最大的傷害,請你幫他計算一下,他的一次攻擊最多能使drd受到多少傷害。
輸入輸出格式
輸入格式:
輸入文件的第 1 行包含 2 個整數,依次為n, m,表示 drd 有n扇防御門,atm 的初始攻擊力為0到m之間的整數。
接下來n行,依次表示每一扇防御門。每行包括一個字符串op和一個非負整數t,兩者由一個空格隔開,且op在前,t在后,op表示該防御門所對應的操作,t表示對應的參數。
輸出格式:
輸出一行一個整數,表示atm的一次攻擊最多使drd受到多少傷害。
說明:
發現每一位是獨立的,我們可以花\(nlogm\)的時間把每一位填0或1的情況的結果存下來
然后似乎可以貪心,我不太清楚
我是對每一位做的DP,用來判斷某位是否可以越界
Code:
#include <cstdio> const int N=1e5+10; struct node {int op,t; }opt[N]; int n,m,to[32][2],dp[32][2];//0表示有限制,1表示沒有 int max(int x,int y){return x>y?x:y;} int main() {scanf("%d%d",&n,&m);char op[6];for(int i=1;i<=n;i++){scanf("%s%d",op,&opt[i].t);if(op[0]=='A') opt[i].op=1;else if(op[0]=='O') opt[i].op=2;else opt[i].op=3;}for(int k=0;k<30;k++){for(int s=0;s<=1;s++){to[k][s]=s;for(int i=1;i<=n;i++){int op=opt[i].op,t=opt[i].t;if(op==1) to[k][s]&=t>>k&1;else if(op==2) to[k][s]|=t>>k&1;else to[k][s]^=t>>k&1;}}}int cnt=0,sum=0,ans=0;for(int p=m;p;p>>=1) ++cnt;for(int k=0;k<30;k++){if(k>=cnt)sum|=to[k][0]<<k;else{if(cnt>k)//不處理最后一位dp[k][1]=dp[k-1][1]|((to[k][0]|to[k][1])<<k);//最大化dp[k][0]=dp[k-1][0]|((to[k][0])<<k);//填0不能隨便用if(m>>k&1)//如果這一位可以填1{dp[k][0]=max(dp[k][0],dp[k-1][0]|(to[k][1]<<k));//填1不能隨便用dp[k][0]=max(dp[k][0],dp[k-1][1]|(to[k][0]<<k));//填0前面隨便用}ans=max(ans,max(dp[k][0],dp[k][1]));}}printf("%d\n",ans+sum);return 0; }2018.9.3
轉載于:https://www.cnblogs.com/butterflydew/p/9577906.html
總結
以上是生活随笔為你收集整理的洛谷 P2114 [NOI2014]起床困难综合症 解题报告的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 练习一
- 下一篇: iOS AVAudioSession 配