日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021牛客暑期多校训练营3A-Guess and lies【dp】

發布時間:2023/12/3 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021牛客暑期多校训练营3A-Guess and lies【dp】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://ac.nowcoder.com/acm/contest/11254/A


題目大意

現在有一個y∈[1,n]y\in[1,n]y[1,n]BobBobBob每次可以選擇問AliceAliceAlice是否y≥xy\geq xyxAliceAliceAlice可以說一次謊。BobBobBob要在最少次數內確定yyy的值,而AliceAliceAlice盡量使得次數最多。

現在已知第一次BobBobBob詢問的是kkkAliceAliceAlice回答了是,對于k∈[1,n]k\in[1,n]k[1,n]求每個kkk BobBobBob需要的最少詢問次數。

1≤n≤20001\leq n\leq 20001n2000


解題思路

dlsdlsdls 在 WC 講的神仙題目。

對于一種情況,假設y=iy=iy=i時,AliceAliceAlice說謊的次數是固定的,記這個次數為aia_iai?,所以如果當1~n1\sim n1n中只有一個數字滿足ai≤1a_i\leq 1ai?1時那么答案就是這個數字了。

然后看BobBobBob的操作,它每次可以選擇一個xxxAliceAliceAlice可以選擇讓≥x\geq xx的數字或者讓<x<x<x的數字的位置ai=ai+1a_i=a_i+1ai?=ai?+1BobBobBob需要用最少的次數使得只有一個位置ai≤1a_i\leq 1ai?1

發現因為每次都是覆蓋一個前綴或者一個后綴,所以如果只保留ai=0/1a_i=0/1ai?=0/1的話那么所有的狀態肯定是若干個111+若干個000+若干個111,分別記為a/b/ca/b/ca/b/c個,我們就可以設狀態為fa,b,cf_{a,b,c}fa,b,c?進行轉移。

考慮到隨著ccc的增大我們肯定會盡量選擇中間的位置,也就是決策位置是單調遞增的,所以我們可以做到O(n3)O(n^3)O(n3)的轉移。

然后注意到這個和猜數字的規則很像,詢問次數級別不會超過log?n\log nlogn,所以我們可以考慮交換次數和一個值域,記fw,a,bf_{w,a,b}fw,a,b?表示猜測了www次能夠猜出來的aaa000+bbb111+ccc000中最大的ccc,然后用決策單調性轉移。

時間復雜度:O(n2log?n)O(n^2\log n)O(n2logn)


code

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=2100;int n,inf,f[20][N][N];int calc(int u,int v){int ans=19;while(ans&&f[ans-1][u][v]>=0)ans--;return ans;}int main(){scanf("%d",&n);memset(f,0xcf,sizeof(f));inf=f[0][0][0];for(int i=0;i<=1;i++)for(int j=0;j<=1-i;j++)f[0][i][j]=1-i-j;for(int i=1;i<=19;i++){for(int j=0;j<=n;j++)for(int k=0;k<=j;k++){int u=f[i-1][j-k][k];int v=f[i-1][k][j-k];if(u!=inf&&v!=inf){u=min(u,n-j);f[i][u][j]=max(f[i][u][j],v);}}for(int j=0;j<=n;j++){int v=f[i-1][j][0];if(v!=inf){for(int k=0;k<=n-j;k++){int u=f[i-1][k][j];if(u==inf)break;f[i][min(u,n-j)][j]=max(f[i][min(u,n-j)][j],v+k);f[i][min(v+k,n-j)][j]=max(f[i][min(v+k,n-j)][j],u);}}}for(int j=0;j<=n;j++)for(int k=n-j-1;k>=0;k--)f[i][k][j]=max(f[i][k][j],f[i][k+1][j]);}for(int i=0;i<n;i++)printf("%d ",calc(i,n-i));return 0;}

總結

以上是生活随笔為你收集整理的2021牛客暑期多校训练营3A-Guess and lies【dp】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。