1. 程式人生 > >牛客網挑戰賽8

牛客網挑戰賽8

做出 自然 過程 block 保留 期望 保留小數 並且 turn

小C現在要參加一場wannafly挑戰賽,一場挑戰賽一共有n道題,一共有m分鐘。
對於第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
(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); }
有一串有n顆珠子的項鏈,每顆珠子上有一個數字,從順時針方向看依次是第1,2,…,n個珠子,第n個珠子之後是第1個珠子。但是小G覺得這串項鏈的造型不夠美觀,他決定用這串項鏈上的珠子造出一個新的項鏈,並且他希望這串新的項鏈是對稱的。
一串項鏈是對稱的,當且僅當存在至少一顆珠子滿足:把它作為起始位置(即順時針和逆時針方向數第0個珠子),對於任意的自然數i,順時針數第i個珠子上的數字和逆時針數第i個珠子上的數字相同。特別的,一個僅有一顆珠子的項鏈也是對稱的。
小G可以使用合成技術將任意正整數顆珠子合成為一個新的珠子,新珠子上的數字=原珠子上的數字的異或和。
用合成技術造出新項鏈的過程是這樣的:最開始由小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