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

给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. 阿里云https+nginx服务搭建

    购买证书 通过控制台进入CA证书服务,点击右上角的购买证书,进入如下图的界面,选择免费的Symantec的DV SSL. 一路点过去,然后回到证书服务主页,会出现一条订单信息,点击补全,如下图所示. ...

  2. 045、Java中使用if语句进行判断

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

  3. 使用Python的PIL库做的图像相似度对比源码备份

    #!/usr/bin/python # Filename: histsimilar.py # -*- coding: utf-8 -*- import PIL.Image def make_regal ...

  4. python matplotlib绘图大全(散点图、柱状图、饼图、极坐标图、热量图、三维图以及热图)

    //2019.7.14晚matplotlib七种常见图像输出编程大全 七种图形汇总输出如下: import numpy as np #导入数据结构nmupy模块import matplotlib.py ...

  5. 【pwnable.kr】cmd2

    这道题是上一个cmd1的升级版 ssh cmd2@pwnable.kr -p2222 (pw:mommy now I get what PATH environmentis for :)) 登录之后, ...

  6. 聊一聊Java中的各种运算符(转载)

    计算机之所以叫"计算机",其最基本用途之一就是运算,对应刚刚接触Java的小伙伴而言,熟悉并掌握Java中的各种运算符及其在表达式中的运算优先级是十分必要的. 算术运算 算术运算主 ...

  7. 075-PHP数组添加元素

    <?php $arr = array(); //定义一个数组,它没有任何元素 echo '增加元素之前数组中元素的个数为:' . count($arr); //输出数组个数 for ($i = ...

  8. Elasticsearch 搜索API

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  9. POJ 1185:炮兵阵地

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 21366   Accepted: 8280 Description ...

  10. EUI库 - 9 - 数据集合 - 数组集合

      ArrayCollection  当数组内的数据被修改了(增删改),组件能有效的获知 myCollection.addEventListener(eui.CollectionEvent.COLLE ...