现在的位置: 首页 > 综合 > 正文

hdu 4876

2019年02月27日 ⁄ 综合 ⁄ 共 930字 ⁄ 字号 评论关闭

思路:暴力剪枝,先在n个中选出k个,然后先不考虑顺序,看所有抑或值能否包括l到ans,不能则退出再选,能则考虑顺序情况。

反思:昨天到今天都曲解题意了。。。wa了几发看别人博客才发现,还有我剪枝太不优越了,T了几发果断重写。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[22];
int b[10];
int n,k,l;
int ans;
bool v[20];
int c[10][10];
bool vis[111];
void check(int num,int sum)
{
    vis[sum]=1;
    if(num==k)return;
    check(num+1,sum);
    check(num+1,sum^b[num]);
}
void go()
{
    memset(vis,0,sizeof(vis));
    check(0,0);
    if(!vis[l])return;
    for(int i=l;i<=ans;i++)if(!vis[i])return;
    do
    {
        memset(vis,0,sizeof(vis));
        for(int i=0;i<k;i++)
        {
            int s=0;
            for(int j=0;j<k;j++)
            {
                s^=b[(i+j)%k];
                vis[s]=1;
            }
        }
        if(!vis[l])continue;
        int x;
        for(x=l;;x++)if(!vis[x])break;
        ans=max(ans,x-1);
    }while(next_permutation(b,b+k));
}
void dfs(int u,int num)
{
    if(num==k)
    {
        go();
        return;
    }
    for(int i=u;i<n;i++)
    {
        b[num]=a[i];
        dfs(i+1,num+1);
    }
}
int main()
{
    while(scanf("%d%d%d",&n,&k,&l)!=EOF)
    {
        for(int i=0; i<n; i++)scanf("%d",&a[i]);
        sort(a,a+n);
        ans=0;
        memset(v,0,sizeof(v));
        dfs(0,0);
        printf("%d\n",ans);
    }
    return 0;
}
【上篇】
【下篇】

抱歉!评论已关闭.