CF11D A Simple Task

垃圾状压dp,应该根本没有紫题难度

设当前状态为state,起点为state包含的元素中最小的一个,防止重复,以及当前所在地点u

注意自环,就是两个点来回走的。在答案里修改也可以。我是直接在ans更新时判断state是否合法,是否包含至少3个元素

然后一个答案会两种时针方式走,所以最终答案要处以2

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[20][600005]={0},ans=0;
int n,m;
int hed[5005],tal[5005],nxt[5005],cnt=0;
inline void addege(int x,int y){
    cnt++;
    tal[cnt]=y;
    nxt[cnt]=hed[x];
    hed[x]=cnt;
}
bool ck(int state){
    int cnt=0;
    for(int i=1;i<=n;i++){
        if((state&(1<<(i-1)))==(1<<(i-1))){
            cnt++;
        }
    }
    if(cnt<=2) return 0;
    return 1;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        addege(x,y);
        addege(y,x);
    }
    for(int i=1;i<=n;i++){
        f[i][1<<(i-1)]=1ll;
    }
    for(int state=1;state<(1<<n);state++){
        int st,u;
        for(int i=1;i<=n;i++){
            if((state&(1<<(i-1)))==(1<<(i-1))){
                st=i;
                break;
            }
        }
        for(int i=1;i<=n;i++){
            if((state&(1<<(i-1)))!=(1<<(i-1))) continue;
            u=i;
            for(int j=hed[u];j;j=nxt[j]){
                int v=tal[j];
                if(v<st) continue;
                if((state&(1<<(v-1)))==(1<<(v-1))){
                    if(v==st&&ck(state)) ans+=f[u][state]/*printf("st:%d,state:%d,f[u][state]:%d\n",st,state,f[u][state])*/;
                }
                else f[v][state|(1<<(v-1))]+=f[u][state];
            }
        }
    }
    cout<<ans/2<<endl;
    return 0;
} 

原文地址:https://www.cnblogs.com/QYJ060604/p/11421046.html

时间: 2024-10-18 21:00:43

CF11D A Simple Task的相关文章

【题解】 CF11D A Simple Task

[题解] CF11D A Simple Task 传送门 \(n \le 20\) 考虑状态压缩\(dp\). 考虑状态,\(dp(i,j,O)\)表示从\(i\)到\(j\)经过点集\(O\)的路径有多少. \(dp(i,j,O \bigcup i)=\Sigma dp(i,p,O)\),\(j-p\)有一条边. 考虑内存,我们可以认定状态压缩串中\(lowbit(x)\)位是一条路的起点,这样我们直接省掉一维.空间限制卡进去了. 考虑答案怎么统计,就是\((\Sigma (dp(i,j,O)

CF11D A Simple Task 状压DP

传送门 \(N \leq 19\)-- 不难想到一个状压:设\(f_{i,j,k}\)表示开头为\(i\).结尾为\(j\).经过的点数二进制下为\(k\)的简单路总数,贡献答案就看\(i,j\)之间有没有边. 当然,会有一些问题:①路会算重:②\(2^NN^2\)的数组开不下(当然②才是重点),所以考虑优化算法 考虑类似最小环的优化 设\(f_{i,j}\)表示开头为\(log_2lowbit(j)\),结尾为\(i\),经过的点数二进制下为\(j\)的简单路总数,转移跟上面类似,值得注意的是

CF11D A Simple Task(状压DP)

\(solution:\) 思路大家应该都懂: 状压DP:\(f[i][j]\),其中 \(i\) 这一维是需要状压的,用来记录19个节点每一个是否已经走过(走过为 \(1\) ,没走为 \(0\) ,用 \(2\)进制 压缩一下即可).同时,我们认为状压中已经走过的序号最小的节点为出发节点,\(j\) 即数组第二维是路径终点.(当这两个数相同时,说明找到了一个环). 注:这种方法因为无向图的存在,会出现(同一条路径出现两次)(一条边和两个端点构成非法环)的情况,这只需要在输出答案时 \(ans

HUST 1341 A - A Simple Task(哈理工 亚洲区选拔赛练习赛)

A - A Simple Task Time Limit:1000MS    Memory Limit:131072KB    64bit IO Format:%lld & %llu SubmitStatusPracticeHUST 1341 Description As is known to all, lots of birds are living in HUST. A bird has s units of food on the first day, and eats k units

计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task

E. A Simple Task Problem's Link: http://codeforces.com/problemset/problem/558/E Mean: 给定一个字符串,有q次操作,每次操作将(l,r)内的字符升序或降序排列,输出q次操作后的字符串. analyse: 基本思想是计数排序. 所谓计数排序,是对一个元素分布较集中的数字集群进行排序的算法,时间复杂度为O(n),但使用条件很苛刻.首先对n个数扫一遍,映射出每个数字出现的次数,然后再O(n)扫一遍处理出:对于数字ai,

A Simple Task

A Simple Task 就像这道题的题目一样,真的是一个简单的题目,题意就是一句话:给一个数N求符合公式N = O * 2P的 O 和 P. 下面我们就一起看一下题吧. Description Given a positive integer n and the odd integer o and the nonnegative integer p such that n = o2^p. Example For n = 24, o = 3 and p = 3. Task Write a pr

HDU1339_A Simple Task【水题】

A Simple Task Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3987    Accepted Submission(s): 2181 Problem Description Given a positive integer n and the odd integer o and the nonnegative integ

杭电 HDU ACM 1339 A Simple Task

A Simple Task Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4180    Accepted Submission(s): 2304 Problem Description Given a positive integer n and the odd integer o and the nonnegative integ

Codeforces 558E A Simple Task (计数排序&amp;&amp;线段树优化)

题目链接:http://codeforces.com/contest/558/problem/E E. A Simple Task time limit per test5 seconds memory limit per test512 megabytes inputstandard input outputstandard output This task is very simple. Given a string S of length n and q queries each quer