(中等) HDU 4979 A simple math problem. , DLX+重复覆盖+打表。
Description
Some people buy multiple accumulated lotteries to guarantee a higher possibility to get the top prize. Despite of this, it’s still not worthy to guarantee a top prize.Knowing this, Dragon changes his target to second tier prize. To get a second tier prize, you need to contain all of the R numbers with M numbers picked.Given N, M and R, Dragon wants to know how many M-accumulated lotteries he needs to buy, so that he can guarantee that he can get at least the second tier prize.
#include<iostream>
#include<cstring> using namespace std; const int MaxN=;
const int MaxM=;
const int MaxNode=MaxN*MaxM;
const int INF=10e8; struct DLX
{
int U[MaxNode],D[MaxNode],L[MaxNode],R[MaxNode],col[MaxNode];
int H[MaxN],S[MaxM];
int ans;
int n,m,size; void init(int _n,int _m)
{
n=_n;
m=_m;
size=m;
ans=INF; for(int i=;i<=m;++i)
{
L[i]=i-;
R[i]=i+;
U[i]=D[i]=i; S[i]=;
}
L[]=m;
R[m]=; for(int i=;i<=n;++i)
H[i]=-;
} void Link(int r,int c)
{
col[++size]=c;
++S[c]; U[size]=U[c];
D[size]=c;
D[U[c]]=size;
U[c]=size; if(H[r]==-)
H[r]=L[size]=R[size]=size;
else
{
L[size]=L[H[r]];
R[size]=H[r];
R[L[H[r]]]=size;
L[H[r]]=size;
}
} void remove(int c)
{
for(int i=D[c];i!=c;i=D[i])
{
L[R[i]]=L[i];
R[L[i]]=R[i];
}
} void resume(int c)
{
for(int i=U[c];i!=c;i=U[i])
L[R[i]]=R[L[i]]=i;
} bool vis1[MaxM]; int getH()
{
int ret=; for(int i=R[];i!=;i=R[i])
vis1[i]=; for(int i=R[];i!=;i=R[i])
if(vis1[i])
{
++ret;
vis1[i]=; for(int j=D[i];j!=i;j=D[j])
for(int k=R[j];k!=j;k=R[k])
vis1[col[k]]=; //!!!!!!!!!!!!!!
} return ret;
} void Dance(int d)
{
if(getH()+d>=ans)
return; if(R[]==)
{
if(d<ans)
ans=d; return;
} int c=R[]; for(int i=R[];i!=;i=R[i])
if(S[i]<S[c])
c=i; for(int i=D[c];i!=c;i=D[i])
{
remove(i); for(int j=R[i];j!=i;j=R[j])
remove(j); Dance(d+); for(int j=L[i];j!=i;j=L[j])
resume(j); resume(i);
}
}
}; DLX dlx;
int N,M,R;
int C[][]; void getC()
{
for(int i=;i<=;++i)
C[i][]=; for(int i=;i<=;++i)
for(int j=;j<=i;++j)
C[i][j]=C[i-][j-]+C[i-][j];
} void numTOp(int *s,int x,int n,int m,int d)
{
if(m<=)
return; if(x>=C[n-][m-])
numTOp(s,x-C[n-][m-],n-,m,d+);
else
{
s[]=d;
numTOp(s+,x,n-,m-,d+);
}
} int pTOnum(int *s1,int *s2)
{
int vis[],ans1=; memset(vis,,sizeof(vis)); for(int i=;i<R;++i)
vis[s1[s2[i]-]]=; int tR=R-; for(int i=;i<=N && tR>=;++i)
{
if(vis[i]==)
ans1+=C[N-i][tR];
else
--tR;
} return ans1;
} void slove()
{
int s[];
int ts[],temp; dlx.init(C[N][M],C[N][R]); for(int i=;i<C[N][M];++i)
{
numTOp(s,i,N,M,); for(int j=;j<C[M][R];++j)
{
numTOp(ts,j,M,R,); temp=pTOnum(s,ts); dlx.Link(i+,temp+);
}
} dlx.Dance(); cout<<dlx.ans<<endl;
} int main()
{
ios::sync_with_stdio(false); int T; cin>>T; getC(); for(int cas=;cas<=T;++cas)
{
cin>>N>>M>>R; cout<<"Case #"<<cas<<": ";
slove();
} return ;
}
把结果保存到文件里然后再复制到一个数组就行了。。。。。。
(中等) HDU 4979 A simple math problem. , DLX+重复覆盖+打表。的更多相关文章
- hdu - 4979 - A simple math problem.(可反复覆盖DLX + 打表)
题意:一种彩票共同拥有 N 个号码,每注包括 M 个号码,假设开出来的 M 个号码中与自己买的注有 R 个以上的同样号码,则中二等奖,问要保证中二等奖至少要买多少注(1<=R<=M< ...
- HDU 1757 A Simple Math Problem 【矩阵经典7 构造矩阵递推式】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=1757 A Simple Math Problem Time Limit: 3000/1000 MS (J ...
- hdu 1757 A Simple Math Problem (乘法矩阵)
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- HDU 1757 A Simple Math Problem (矩阵快速幂)
题目 A Simple Math Problem 解析 矩阵快速幂模板题 构造矩阵 \[\begin{bmatrix}a_0&a_1&a_2&a_3&a_4&a ...
- HDU 1757 A Simple Math Problem(矩阵)
A Simple Math Problem [题目链接]A Simple Math Problem [题目类型]矩阵快速幂 &题解: 这是一个模板题,也算是入门了吧. 推荐一个博客:点这里 跟 ...
- HDU 1757 A Simple Math Problem (矩阵乘法)
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- hdu 5974 A Simple Math Problem
A Simple Math Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Ot ...
- hdu 1757 A Simple Math Problem(矩阵快速幂乘法)
Problem Description Lele now is thinking about a simple function f(x). If x < f(x) = x. If x > ...
- HDU 1757 A Simple Math Problem(矩阵高速幂)
题目地址:HDU 1757 最终会构造矩阵了.事实上也不难,仅仅怪自己笨..= =! f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + -- + a9 ...
随机推荐
- 转: Windows如何打开和使用事件查看器管理计算机
方法/步骤 1 右键单击"我的电脑"(win8中名称为"这台电脑.This Computer"),选择"管理",点击. 步骤阅读 2 出 ...
- 超棒的自定义超酷滚动条jQuery插件 - Perfect Scrollbar
可能大家厌倦了千篇一律的页面滚动条,如果你希望能够设计出与众不同的页面UI设计的话,Perfect ScrollBar可能就是你寻找的解决方案. 这个滚动条来自于一个个人项目,一个简单但是非常棒的滚动 ...
- linux的学习系列 1---简介
Linux简介 严格的来讲,Linux 不算是一个操作系统,只是一个 Linux 系统中的内核,即计算机软件与硬件通讯之间的平台:Linux的全称是GNU/Linux,这才算是一个真正意义上的Linu ...
- ReactiveCocoa的冷信号与热信号 探讨
背景 ReactiveCocoa(简称RAC)是最初由GitHub团队开发的一套基于Cocoa的FRP框架.FRP即Functional Reactive Programming(函数式响应式编程), ...
- HDU ACM 1495 非常可乐(广搜BFS)
非常可乐 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Total Submissi ...
- KNN邻近分类算法
K邻近(k-Nearest Neighbor,KNN)分类算法是最简单的机器学习算法了.它采用测量不同特征值之间的距离方法进行分类.它的思想很简单:计算一个点A与其他所有点之间的距离,取出与该点最近的 ...
- 使用NGUI进行类似Button的操作
下面例子以Label和Sprite为例,进行说明如何在NGUI中对控件添加单击响应的事件方法. 首先在UIRoot下添加Label控件,然后Scene场景中右键Label-->Attach--& ...
- Linux 下 git的使用
参考链接:http://www.liaoxuefeng.com 安装 安装步骤: ①先给操作系统装入git工具,以Linux为例: $ sudo apt-get install git ②去githu ...
- ActionBar的简单使用
只简单实现了一下ActionBar的使用,在右上角添加两个ActionBar,在左上角实现默认的返回箭头,类似于微信朋友圈的 这是MainActivity的代码: public class MainA ...
- JSON缺包导致的错误
Json-lib 需要的 jar 包 commons-beanutils-1.8.3.jar commons-collections-3.2.1.jar commons-lang-2.6.jar co ...