黑题首杀——大佬
这是Noip模拟四的T4,当时一看题目就知其不凡
果然,竟然是我OI生涯第一个要面对的黑题
不过吐槽一下,做题就做题吧,你把题面出的这么逗逼很难让人读题的时候不笑出声。。。。
正解(六维信队)
没有烧脑的思维含量,只有永恒的代码能力;
要想考试碾压标程,还是得看我们信队!!(尽管本人信队菜展了)
单单几行得满自己想要的最多的分,半个小时敲出理想远方。。。。。。
(不知道有没有广告费呢?)
引借一下zxs童鞋的码码,供ID为wsn的mzs童鞋学习:
1 bool dp(int ti,int m,int f,int l,int c,int num) 2 { 3 if(!c) return 1; 4 if(c<0) return 0; 5 if(ti>n) return 0; 6 m-=a[ti]; 7 if(m<0) return 0; 8 if(dp(ti+1,m,f,l,c-1,num)) return 1; 9 if(dp(ti+1,min(mc,m+w[ti]),f,l,c,num)) return 1; 10 if(dp(ti+1,m,f,l+1,c,num)) return 1; 11 if(dp(ti+1,m,f*l,l,c,num)) return 1; 12 if(num<2&&dp(ti+1,m,1,0,c-f,num+1)) return 1; 13 return 0; 14 }
现在,然我们瞧一瞧满分思路
通过审题,我们可以知道,每天辣鸡只会使用五个中的一个技能。
而我们可以发现,怼darklao与刷水题可以分开。
于是情况可以分为两个且唯一关联就是时间day,总共30天(样例里)。于是:
方案一:水题续命
称之续命,是要找到辣鸡最少刷几天水题保证自己不死。f[i][j]表示在第i天自信值为j的情况下刷水题的天数。 则可以得到状态转移方程:
不刷水题:
f[i][j-a[i]]=max(f[i][j-a[i]],f[i-1][j]+1)
刷水题:
int J=min(j-a[i]+w[i],mc);
f[i][J]=max(f[i-1][j],f[i][J]);
方案二:怒怼大佬
保了自己命之后就可以开始怼大佬了!!
那么注意到只能够开两次大,则需要分成几种不同的情况:
1.一次不开就可以干掉
2.开一次可以干掉
3.大招全开
但在干这些事之前,我们需要把辣鸡的每天可能的等级,威力,天数存起来,并且注意去重。如果不去重,会导致,嘲讽值和天数多次一样的话,会导致最后计算三种情况时,将一天算成多天
那么,剩下的就看咱们的English到不到位了(尽管wsn用了些许汉语拼音,而且语法不太正确。。。)
1 #include<bits/stdc++.h> 2 #define int long long 3 #define Day second 4 #define Attack first 5 using namespace std; 6 inline int read(){ 7 int x=0,f=1; char ch=getchar(); 8 while(ch<'0'||ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } 9 while(ch>='0'&&ch<='9'){ x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); } 10 return x*f; 11 } 12 const int NN=105,momo=1e6+7; 13 int n,m,mc,a[NN],w[NN],C[NN]; 14 int day,f[NN][NN]; 15 struct MZS{ int up_day,F,L; };//sign the level_up day and the attack and the level 16 pair<int,int> zu[1000010]; int cnt; 17 int dalao_Cmax; 18 struct HASH{ 19 struct node{int x,y,next;}e[1000010];int r[1000010],tot; 20 inline void add(int x,int y){//add to check repeat 21 int pw=(1ll*x*131+y)%momo; 22 e[++tot]=(node){x,y,r[pw]}; 23 r[pw]=tot; 24 } 25 inline bool check(int x,int y){//whether repeat or not 26 int pw=(1ll*x*131+y)%momo; 27 for(int i=r[pw];i;i=e[i].next) 28 if(e[i].x==x&&e[i].y==y) return true;//find have repeat line 29 return false;//not repeat 30 } 31 }Map; 32 inline void DAY(){ 33 for(int i=1;i<=n;i++)//day 34 for(int j=a[i];j<=mc;j++)//yourself confidence 35 { 36 f[i][j-a[i]]=max(f[i][j-a[i]],f[i-1][j]+1);//only heat by darklao 37 int J=min(j-a[i]+w[i],mc);//make sure that your confidence is not over_added 38 f[i][J]=max(f[i-1][j],f[i][J]);//do some water problem and heat by darklao 39 //also the maxn day you can attack darklao 40 } 41 for(int i=1;i<=n;i++) 42 for(int j=1;j<=mc;j++) 43 day=max(day,f[i][j]);//find the day that you can do minn(water problems) 44 } 45 inline void DUI(){ 46 queue<MZS> Q;//use to record the day you improve yourself,your attack_value and level 47 Q.push((MZS){1,1,0});//give the queue a start value 48 while(!Q.empty()){ 49 MZS q=Q.front(); Q.pop(); 50 if(q.up_day==day) continue; 51 Q.push((MZS){q.up_day+1,q.F,q.L+1});//level up 52 if(q.L>1&&1ll*q.F*q.L<=1ll*dalao_Cmax&&!Map.check(q.F*q.L,q.up_day+1)){ 53 //make sure one attack and level only record once 54 Q.push((MZS){q.up_day+1,q.F*q.L,q.L});//attack_value up 55 zu[++cnt]=make_pair(q.F*q.L,q.up_day+1);//record the level and attack situaton 56 Map.add(q.F*q.L,q.up_day+1);////record the level and attack situaton 57 } 58 } 59 } 60 namespace WSN{ 61 inline int main(){ 62 n=read(),m=read(),mc=read(); 63 for(int i=1;i<=n;i++) a[i]=read(); 64 for(int i=1;i<=n;i++) w[i]=read(); 65 for(int i=1;i<=m;i++) C[i]=read(),dalao_Cmax=max(dalao_Cmax,C[i]); 66 DAY(); DUI(); 67 sort(zu+1,zu+cnt+1);//up_sort 68 for(int i=1;i<=m;i++){ 69 if(C[i]<=day) {puts("1"); continue; }//not to Dui darklao,use "1" to kill him 70 bool flag=0; int minn=1e9; 71 for(int j=cnt,k=1;j;j--){//two signed mark to ensure the range and bool 72 while(k<cnt && zu[k].Attack+zu[j].Attack<=C[i]) 73 //before k to the end ,the sum of attack is less than the confidence od darklao 74 minn=min(minn,zu[k].Day-zu[k].Attack),k++;//use mark "k" to go through the "zu" 75 //find the minn of "cha zhi" 76 if(minn<=(day-zu[j].Day)-(C[i]-zu[j].Attack))//Dui twice 77 {flag=1; break;}//use the "cha zhi" in while to judge this darklao 78 if(zu[j].Attack<=C[i]&&C[i]-zu[j].Attack<=day-zu[j].Day)//Dui once 79 {flag=1; break;}// 80 } 81 puts(flag? "1": "0"); 82 } 83 return 0; 84 } 85 } 86 signed main(){return WSN::main();}
就到这里吧,第一道黑题没想到题面这么豆比。。。。。

浙公网安备 33010602011771号