HGOI20180822 五校联考卷

T1

【题目意思】给出下列程序片段,预测程序运行结果

输入文件为T(T<=200)组数据,每组数据有个n(n<=1014)

输出文件为T行,每行一个数据,表示fun(n)的值

simple input:
3
4
2
5
simple output:
3
2
2

唯一分解定理可知:

 

 所以

 

 

 

所以,  

深入分析发现首先ai和bi中必然有一个是ci而且另外一个的取值范围一定是[0,ci]之间 

所以排列组合一下就是2ci+1种可能,对于每种可能的情况答案就是

 注意到程序只记录一遍而且存在平方数的存在,这样我们的答案就是这样

 

T2

【题目大意】 给出一个序列长度为n(n<=1000)有且仅有数字1-8组成,求出一个最长的子序列满足

1.子序列中相同元素排在一起

2.数字1-8各自出现的次数相差不多于1(最多相差1),没出现的按照0计算。

simple input:
8
8 7 6 5 4 3 2 1
simple output
8

 

# include<bits/stdc++.h>
using namespace std;
int f[1001][126][256];//f[前i个数字,每个最少出现个数,选取的状态]=最长子序列的长度 
int a[1001],ans,n;
void dfs(int w,int v,int i)
{
    if (w==9) {
        int lastv=v-(1<<(8-a[i]));
        int cnt=1;
        for (int k=i-1;k>=0;k--) 
        {
            f[i][cnt][v]=max(f[i][cnt][v],f[k][cnt][lastv]+cnt);
            f[i][cnt-1][v]=max(f[i][cnt-1][v],f[k][cnt-1][lastv]+cnt);
            if (a[k]==a[i]) cnt++;
            if (cnt>125) return;
        }
        return;
    }
    if (w!=a[i]) dfs(w+1,v*2,i);
    dfs(w+1,v*2+1,i);
}
int main()
{
    scanf("%d",&n);
    memset(f,128,sizeof(f));
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    for (int i=1;i<=255;i++) f[0][0][i]=0;
    for (int i=1;i<=125;i++) f[0][i][0]=0;
    for (int i=1;i<=n;i++) {
        dfs(1,0,i);
        for (int j=0;j<=125;j++) 
         ans=max(ans,f[i][j][255]);
    }
    printf("%d\n",ans);
    return 0;
 } 

 

posted @ 2018-08-22 17:09  ljc20020730  阅读(106)  评论(0编辑  收藏  举报