zoukankan      html  css  js  c++  java
  • [bzoj1879][Sdoi2009]Bill的挑战_动态规划_状压dp

    Bill的挑战 bzoj-1879 Sdoi-2009

    题目大意

    注释:$1le t le 5$,$1le m le 15$,$1le length le 50$。


    想法

    又是一个看数据范围想做法的题,我们想到状压dp。

    看了题解... ...网上给的状态是f[len][s]表示长度为len满足状态s的字符串个数。

    光看状态... ...可能算重啊?!

    其实... ...

    状态:dp[len][s]表示长度为len,能且只能满足状态为s的字符串个数。

    转移:我们先预处理出g[i][c]表示第i位能放字符c的字符串状态,转移就是dp[len][s^g[len][c]]+=dp[len-1][s]表示在dp[len-1][s]的所有方案中所有的字符串后面加上c能满足的字符串。这样仍然满足“能且只能”的条件。

    最后,附上丑陋的代码... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define mod 1000003
    using namespace std;
    int f[55][1<<16],ans,len,g[55][27],t,cases,n,k;
    char s[20][100];
    int main()
    {
    	scanf("%d",&cases);
    	while (cases--)
    	{
    		memset(f,0,sizeof(f));
    		memset(g,0,sizeof(g)); 
    		scanf("%d%d",&n,&k); ans=0;
    		for (int i=1;i<=n;i++) scanf("%s",s[i]);
    		f[0][(1<<n)-1]=1;
    		len=strlen(s[1]);
    		for(int i=1;i<=len;i++) for(int j=0;j<26;j++)
    		for(int k=1;k<=n;k++)
    		{
    			if (s[k][i-1]=='a'+j||s[k][i-1]=='?')  g[i][j]|=1<<(k-1);
    		}
    		for(int i=1;i<=len;i++) for(int j=0;j<(1<<n);j++)
    		{
    			if(!f[i-1][j]) continue;
    			for(int k=0;k<26;k++) (f[i][g[i][k]&j]+=f[i-1][j])%=mod;
    		}
    		for(int i=0;i<(1<<n);i++)
    		{
    			int t(0),x=i;
    			while(x)
    			{
    				if(x%2) t++;
    				x/=2;
    			}
    			if(t==k)(ans+=f[len][i])%=mod;
    		} 
    		printf("%d
    ",ans);
    	}
    	return 0;
    } 
    

    小结:看数据范围想做法其实很实用,比如说我们拿到一道题,如果这个数据范围是卡这正解的数据范围出的话,我们就会往一些比较常见的复杂度上想,加快了解题速度。

  • 相关阅读:
    LeetCode Path Sum
    实训篇-Html-表单练习
    实训篇-Html-frameset框架集
    实训篇-Html-超链接练习
    实训篇-Html-列表练习
    实训篇-Html-表格练习2
    实训篇-Html-表格练习1
    实训篇-Html-超链接a标签使用
    实训篇-Html-多媒体标签
    实训篇-Html-标题,段落,字体
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9380094.html
Copyright © 2011-2022 走看看