zoukankan      html  css  js  c++  java
  • UVA-11795 (状压dp)

    题意:

    按照一定的顺序消灭n个机器人,每消灭一个机器人就可得到它的武器,每个机器人只有用特定的武器才能消灭,现在给定一个初始的武器,它能消灭一些机器人,每个机器人的武器能消灭那些机器人也给你了,现在要你求消灭n个机器人的顺序总数;

    思路:

    dp[i][k]表示在第i次操作时的用k表示已经挂掉的机器人的操作顺序数;

    枚举第i次要攻击的机器人j;dp[i][x]+=dp[i-1][k];x是挂到j后k与j表示的状态;

    AC代码:

    /************************************************ 
    ┆  ┏┓   ┏┓ ┆    
    ┆┏┛┻━━━┛┻┓ ┆ 
    ┆┃       ┃ ┆ 
    ┆┃   ━   ┃ ┆ 
    ┆┃ ┳┛ ┗┳ ┃ ┆ 
    ┆┃       ┃ ┆  
    ┆┃   ┻   ┃ ┆ 
    ┆┗━┓    ┏━┛ ┆ 
    ┆  ┃    ┃  ┆       
    ┆  ┃    ┗━━━┓ ┆ 
    ┆  ┃  AC代马   ┣┓┆ 
    ┆  ┃           ┏┛┆ 
    ┆  ┗┓┓┏━┳┓┏┛ ┆ 
    ┆   ┃┫┫ ┃┫┫ ┆ 
    ┆   ┗┻┛ ┗┻┛ ┆       
    ************************************************ */  
    
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bits/stdc++.h>
    #include <stack>
    
    using namespace std;
    
    #define For(i,j,n) for(int i=j;i<=n;i++)
    #define mst(ss,b) memset(ss,b,sizeof(ss));
    
    typedef  long long LL;
    
    template<class T> void read(T&num) {
        char CH; bool F=false;
        for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
        for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
        F && (num=-num);
    }
    int stk[70], tp;
    template<class T> inline void print(T p) {
        if(!p) { puts("0"); return; }
        while(p) stk[++ tp] = p%10, p/=10;
        while(tp) putchar(stk[tp--] + '0');
        putchar('
    ');
    }
    
    const LL mod=1e9+7;
    const double PI=acos(-1.0);
    const int inf=1e9;
    const int N=(1<<18);
    const int maxn=(1<<8);
    const double eps=1e-8;
    
    char s[20][20];
    int num[20],sword[N],n;
    LL dp[18][N];
    inline int getnum(int x)
    {
       // int len=strlen(s[x]);
        int ans=0;
        For(i,0,n-1)
        {
            if(s[x][i]=='1')ans+=(1<<i);
        }
        return ans;
    }
    int main()
    {       
            int t,Case=0;
            read(t);
            while(t--)
            {
                read(n);
                scanf("%s",s[0]);
                sword[0]=getnum(0);
                mst(dp,0);
                For(i,1,n)
                {
                    scanf("%s",s[i]);
                    num[i]=getnum(i);
                }
                For(i,1,(1<<n)-1)//预处理出每个状态下得到的武器情况
                {
                    sword[i]=sword[0];
                    for(int j=0;j<n;j++)
                    {
                        if(i&(1<<j))sword[i]=(sword[i]|num[j+1]);
                    }
                }
                dp[0][0]=1;
                For(i,1,n)
                {
                    For(j,1,n)
                    {
                        for(int k=0;k<(1<<n);k++)
                        {
                            if(k&(1<<(j-1)))continue;//如果第j个机器人已经挂掉就略过;
                            if(sword[k]&(1<<(j-1)))dp[i][k|(1<<(j-1))]+=dp[i-1][k];//如果有干掉第j个机器人的武器
                        }
                    }
                }
                LL ans=dp[n][(1<<n)-1];
                printf("Case %d: %lld
    ",++Case,ans);
            }
            return 0;
    }
    

      

      

  • 相关阅读:
    ActiveSync合作关系对话框的配置
    WINCE对象存储区(object store)
    Wince 隐藏TASKBAR的方法
    Wince输入法换肤换语言机制
    poj 3080 Blue Jeans 解题报告
    codeforces A. Vasily the Bear and Triangle 解题报告
    hdu 1050 Moving Tables 解题报告
    hdu 1113 Word Amalgamation 解题报告
    codeforces A. IQ Test 解题报告
    poj 1007 DNA Sorting 解题报告
  • 原文地址:https://www.cnblogs.com/zhangchengc919/p/5719705.html
Copyright © 2011-2022 走看看