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

给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. Educational Codeforces Round 63 选做

    D. Beautiful Array 题意 给你一个长度为 \(n\) 的序列.你可以选择至多一个子段,将该子段所有数乘上给定常数 \(x\) .求操作后最大的最大子段和. 题解 考虑最大子段和的子段 ...

  2. android studio 入门坑

    安装 android studio,碰到下面这个图片,直接跳过. 安装时候,选择自定义设置,里面可以配置 sdk 的存放位置. 新建工程后,gradle sync 比较慢,可以 修改工程中的 buil ...

  3. 一文详解scala泛型及类型限定

    今天知识星球球友,微信问浪尖了一个spark源码阅读中的类型限定问题.这个在spark源码很多处出现,所以今天浪尖就整理一下scala类型限定的内容.希望对大家有帮助. scala类型参数要点 1. ...

  4. 基于 Annotation 的装配(注解)

    注解:就是一个类,使用@注解名称 开发中:使用注解 取代 xml配置文件. 1. @Component取代<bean class=""> @Component(&quo ...

  5. 【linux】linux系统安全设置

    1.下载安装安全软件 2.取消Telnet登录采用SSH方式并更改ssh服务端远程登录的配置 1)Telnet登录协议是明文不加密不安全,所以采用更安全的SSH协议. 2)更改ssh服务端远程登录相关 ...

  6. 036-PHP闭包函数的域限制,与如何向闭包函数传递变量

    <?php // 闭包函数的域限制,与如何向闭包函数传递变量 # 隐藏上面的代码,我们最后再来试下 function demo($ATxt) { $func = function () use ...

  7. 163-PHP 文本替换函数str_replace(四)

    <?php $str='Hello world!'; //定义源字符串 $search=array('o','l','w'); //定义将被替换的字符数组 $replace=array('1', ...

  8. [题解] LuoguP3784 [SDOI2017]遗忘的集合

    要mtt的题都是...... 多补了几项就被卡了一整页......果然还是太菜了...... 不说了......来看100分的做法吧...... 如果做过付公主的背包,前面几步应该不难想,所以我们再来 ...

  9. 九、React中的组件、父子组件、React props父组件给子组件传值、子组件给父组件传值、父组件中通过refs获取子组件属性和方法

    一.概述 React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. [父子组件]:组件的相互调用中,我们把调用者称为父 ...

  10. jQuery中:first,:first-child,first()的使用区别

    ul li:first  先获取页面中所有li节点对象数组,然后返回数组中的第一个li节点对象 . :first-child  选择器选取属于其父元素的第一个子元素的所有元素. first() 返回被 ...