牛客網挑戰賽8
阿新 • • 發佈:2018-01-20
做出 自然 過程 block 保留 期望 保留小數 並且 turn 小C現在要參加一場wannafly挑戰賽,一場挑戰賽一共有n道題,一共有m分鐘。
對於第i道題,小C解決它需要恰好j分鐘的概率是pi,j。
小C每次會選擇某一道沒做完的題,然後把它解決(不能中途放棄),之後再決策下一道要做的題是哪道。
求小C在最優策略下,期望能做出幾道題。
小G可以使用合成技術將任意正整數顆珠子合成為一個新的珠子,新珠子上的數字=原珠子上的數字的異或和。
對於第i道題,小C解決它需要恰好j分鐘的概率是pi,j。
小C每次會選擇某一道沒做完的題,然後把它解決(不能中途放棄),之後再決策下一道要做的題是哪道。
求小C在最優策略下,期望能做出幾道題。
輸入描述:
第一行兩個正整數n,m
接下來一共n行,每行有m個小數,第i行的第j個小數表示p
i,j
(這裏假設不存在0分鐘A題的dalao)。
輸出描述:
輸出一個小數,表示期望能做出幾道題,保留小數點後五位。示例1
輸入
2 5 0.2 0.2 0.2 0.2 0.2 0 0.25 0.25 0.25 0.25
輸出
1.30000
#include<cstdio> #include<algorithm> using namespace std; double ans,dp[1<<8][200],a[8][200]; int n,m; int main(){ scanf("%d%d",&n,&m); for(int i=0;i<n;++i) for(int j=1;j<=m;++j) scanf("%lf",&a[i][j]); for(int i=1;i<(1<<n);++i) for(int j=1;j<=m;++j) {for有一串有n顆珠子的項鏈,每顆珠子上有一個數字,從順時針方向看依次是第1,2,…,n個珠子,第n個珠子之後是第1個珠子。但是小G覺得這串項鏈的造型不夠美觀,他決定用這串項鏈上的珠子造出一個新的項鏈,並且他希望這串新的項鏈是對稱的。(int x=0;x<n;++x) if((1<<x)&i) { double t=0; for(int y=1;y<=j;++y) t+=(dp[i^(1<<x)][j-y]+1)*a[x][y]; dp[i][j]=max(dp[i][j],t); ans=max(ans,dp[i][j]); } } printf("%.5f\n",ans); }
一串項鏈是對稱的,當且僅當存在至少一顆珠子滿足:把它作為起始位置(即順時針和逆時針方向數第0個珠子),對於任意的自然數i,順時針數第i個珠子上的數字和逆時針數第i個珠子上的數字相同。特別的,一個僅有一顆珠子的項鏈也是對稱的。
用合成技術造出新項鏈的過程是這樣的:最開始由小G確定一個能整除n的正整數k和一個原項鏈中的起始位置,之後從起始位置開始順時針方向取連續的k個珠子,合成一個新的珠子作為新項鏈的第1個珠子,再取接下來連續的k個珠子,合成一個新的珠子作為新項鏈的第2個珠子,……,直到取完原項鏈的所有珠子為止。註意,合成的新珠子會直接放到新項鏈的位置,並不會插入原項鏈之中參與之後合成過程。新項鏈同樣滿足從順時針方向看依次是第1,2,…,n個珠子,第n個珠子之後是第1個珠子。小G希望新的項鏈上的珠子盡可能多,問新項鏈上的珠子最多有多少個。
輸入描述:
第一行一個整數n。
第二行n個整數,第i個整數a
i
代表原項鏈上第i個珠子上的數字。
輸出描述:
共一行一個整數,代表新項鏈的最大珠子數量。示例1
輸入
5 9 3 9 1 1
輸出
5示例2
輸入
9 7 8 6 5 4 3 1 2 15
輸出
3
備註:
1 ≤ n ≤ 2 x 10^5
#include<cstdio> #include<algorithm> using namespace std; const int N=4e5+88; int n,S[N],a[N],p[N],Xor[N]; bool mar(int length) { S[0]=-5,S[length+1]=-6; int id=0,mx=0,ans=0; for(int i=1;i<=length;++i) { if(mx>i) p[i]=min(mx-i,p[2*id-i]);else p[i]=1; while(S[i-p[i]]==S[i+p[i]]) ++p[i]; if(i+p[i]>mx) mx=i+p[i],id=i; ans=max(ans,p[i]); } return ans>=length/4+1; } bool solve(int y){ for(int i=1;i<=y;++i) { int tot=0; for(int j=i;j<=i+2*n-1;j+=y) S[++tot]=Xor[j+y-1]^Xor[j-1]; if(mar(tot)) return 1; } return 0; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]),a[i+n]=a[i]; for(int i=1;i<=2*n;++i) Xor[i]=a[i],Xor[i]^=Xor[i-1]; for(int i=1;i<=n;++i) if(n%i==0) if(solve(i)) { printf("%d\n",n/i);break; } }
牛客網挑戰賽8