这个题目搁置了这么久,终于搞完了。

给n个人分配n个课程,已经告诉了你n个人对哪几门感兴趣,问最多有多少种分配方式

我刚开始都没找到这怎么还可以状态dp,哪来的状态转移,想用暴力DFS,果断TLE的妥妥的。

后来给殷犇发了这个题目,他还说你刷个这水题还刷得这包子劲,这题目就是后一行的状态由前一行得到,枚举当前这一行分配的状态,如果可行,就从后面的状态加过来

由于状态只是从上一行转移过来,所以可以用滚动数组,用p表示当前,则!p就为上一行的,每次结束再把p置反即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
int n;
int sta[];
ll dp[][<<];
int calc[][<<],cnt[];
void init()
{
memset(calc,,sizeof calc);
memset(cnt,,sizeof cnt);
for (int i=;i<(<<);i++) //这里把只有一门课 两门。。。N门课全部用一个数组存起来,calc[i][]就代表有i个课程的状态,因为不止一种 所以开了两维。
{
int tmp=;
for (int j=i;j;j>>=)
{
if (j&)
tmp++;
}
calc[tmp][cnt[tmp]++]=i;
}
}
int main()
{
int t,a;
scanf("%d",&t);
init();
while (t--)
{
scanf("%d",&n);
for (int i=;i<n;i++)
{
sta[i]=;
for (int j=;j<n;j++)
{
scanf("%d",&a);
if (a==)
{
sta[i]+=<<j;//存入学生感兴趣的课程的状态。
}
}
} int p=,all=(<<n)-;
//memset(dp,0,sizeof dp);
dp[][]=;
for (int i=;i<n;i++)//从第0个人循环到第n-1个人
{
for (int k=,s=calc[i+][k];k<cnt[i+]&&calc[i+][k]<=all;s=calc[i+][++k])//当前是第i号人 则状态必定是calc[i+1][]的状态,比如第三个人就只分配三个课程即可,一旦可行 就从分配了两个课程的状态那里转移过来。
{
dp[p][s]=;
for (int j=;j<n;j++)//逐个试探第j号课程是否可以
{
//dp[p][k]=0;
if (((<<j)&sta[i])==) continue;
if ((<<j)&s)
{
//dp[p][k]+=1; dp[p][s]+=dp[p^][(<<j)^s];//一旦该状态可以,则从上一次的不含新分配的课程的那里转移过来
} //else
// dp[p][k]+=dp[p^1][k];
}
}
p^=;
}
printf("%lld\n",dp[p^][all]);
}
return ;
}

SPOJ 423 Assignments 状态DP的更多相关文章

  1. hdu 4614 pieces 状态DP

    题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:htt ...

  2. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  3. POJ 3254 压缩状态DP

    题意:一个矩形网格,可以填0或1, 但有些位置什么数都不能填,要求相邻两个不同时为1,有多少种填法.矩形大小最大 12*12. 压缩状态DP大多有一个可行的state的范围,先求出这个state范围, ...

  4. 【状态DP】 HDU 1074 Doing Homework

    原题直通车:HDU  1074  Doing Homework 题意:有n门功课需要完成,每一门功课都有时间期限t.完成需要的时间d,如果完成的时间走出时间限制,就会被减 (d-t)个学分.问:按怎样 ...

  5. Hdu 4539 【状态DP】.cpp

    题意: 一个炮兵可以攻打和他之间曼哈顿距离为2的士兵,给出你一块n*m的战场,告诉你哪些地方可以站人哪些地方不可以,问你最多可以安放多少个士兵? n <= 100, m <= 10 思路: ...

  6. hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)

    http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...

  7. hdu 5135(2014广州—状态dp)

    t题意:给你n条边,构造任意个三角形,一个三角形恰好只用3条边,每条边只能一次,求面积最大值 思路: 最开始想的是先排序从大到小取,但感觉并不怎么靠谱. 最多12条边,所以可以求出所有可能的三角形面积 ...

  8. Hdu 3001 Travelling 状态DP

    题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进 ...

  9. lightoj 1244 - Tiles 状态DP

    思路:状态DP dp[i]=2*dp[i-1]+dp[i-3] 代码如下: 求出循环节部分 1 #include<stdio.h> 2 #define m 10007 3 int p[m] ...

随机推荐

  1. 014、Java中byte自动转型的操作

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  2. 015.Delphi插件之QPlugins,FMX插件窗口

    内嵌FMX的插件窗口,效果还是很可以的.退出时,会报错,很诡异啊. 主窗口代码如下 unit Frm_Main; interface uses Winapi.Windows, Winapi.Messa ...

  3. Java If ... Else

    章节 Java 基础 Java 简介 Java 环境搭建 Java 基本语法 Java 注释 Java 变量 Java 数据类型 Java 字符串 Java 类型转换 Java 运算符 Java 字符 ...

  4. 05 MySQL数据类型的选择与使用

    数据类型的选择     1.CHAR与VARCHAR           存储/检索的方式不同.         CHAR是固定长度,而VARCHAR是可变长度         非SQLMode下,超 ...

  5. MQTT 协议学习:008-在STM32上移植MQTT

    前言 通过前面了解MQTT有关概念.分析了有关的报文,我们对于这个协议也有了更深的认识.但纸上谈来终觉浅,绝知此事要躬行. 本文参考:<STM32+W5500+MQTT+Android实现远程数 ...

  6. P1046 划拳

    P1046 划拳 转跳点:

  7. P1047 编程团体赛

    转跳点:

  8. 浅谈arduino的bootloader

    在arduino的板子上,作为核心的avr单片机往往都会烧录一个bootloader,这个叫做bootloader的东东其实是arduino研发团队针对arduino板子开发的一小段代码,借助于这段代 ...

  9. Vulkan Device Memory

    1.通过下面的接口,可以获得显卡支持的所有内存类型: MemoryType的类型如下: 2.引用索引3对内存的描述 我们可以通过调用vkGetPhysicalDeviceMemoryPropertie ...

  10. 如何通过模仿提升Paper写作能力?

    对于大部分初到国外留学的中国留学生们来说要想自己独立完成一篇Paper可能难度会很大,从Paper字体字号要求.Paper写作格式.Paper写作结构等等诸多因素都会影响留学生们写Paper的效率.对 ...