FZU 2200 cleaning dp+预处理
2015-10-06 19:13
309 查看
Problem 2200 cleaning
Accept: 10 Submit: 11
N个人围成一圈在讨论大扫除的事情,需要选出K个人。但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法。
第一行包含一个数T(T<=100),表示测试数据的个数。
接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N)。
输出满足题意的方案数,方案数很大,所以请输出方案数mod 1,000,000,007 后的结果。
24 28 3
416
链接:http://acm.fzu.edu.cn/problem.php?pid=2200
做法:
dp 一维,第几个人,第二维是已经选了几个人,第三维是当前的状态,0 表示当前这位没选,前一位也没选,1表示当前这位没选,前一位选了,2,3类似。
枚举开头两个人的状态,然后预处理dp ,当处理到 i+2 的时候,如果状态和开始枚举的一样,就把值加进real[i]中。预处理出来的real就是最后的答案
Accept: 10 Submit: 11
Time Limit: 1000 mSec Memory Limit : 65536 KB
Problem Description
N个人围成一圈在讨论大扫除的事情,需要选出K个人。但是每个人与他距离为2的人存在矛盾,所以这K个人中任意两个人的距离不能为2,他们想知道共有多少种方法。
Input
第一行包含一个数T(T<=100),表示测试数据的个数。接下来每行有两个数N,K,N表示人数,K表示需要的人数(1<=N<=1000,1<=K<=N)。
Output
输出满足题意的方案数,方案数很大,所以请输出方案数mod 1,000,000,007 后的结果。
Sample Input
24 28 3
Sample Output
416链接:http://acm.fzu.edu.cn/problem.php?pid=2200
做法:
dp 一维,第几个人,第二维是已经选了几个人,第三维是当前的状态,0 表示当前这位没选,前一位也没选,1表示当前这位没选,前一位选了,2,3类似。
枚举开头两个人的状态,然后预处理dp ,当处理到 i+2 的时候,如果状态和开始枚举的一样,就把值加进real[i]中。预处理出来的real就是最后的答案
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <malloc.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <stack> #include <queue> #include <vector> #include <deque> #include <set> #include <map> #define ll long long//试试 ll dp[1010][1010][4];//人数 ll real[1010][1010]; ll mod = 1000000007; void init() { memset(real,0,sizeof real); for(int i=0;i<2;i++)//1 { for(int j=0;j<2;j++)//2 { memset(dp,0,sizeof dp); dp[2][0][i+j*2]=1; for(int ii=3;ii<=1002;ii++)//位置 { for(int jj=0;jj<=ii+2;jj++)//人数 { for(int a=0;a<4;a++)//前一个 { if((a&2)==0) dp[ii][jj][0]=(dp[ii][jj][0]+dp[ii-1][jj][a])%mod; if((a&2)) dp[ii][jj][1]=(dp[ii][jj][1]+dp[ii-1][jj][a])%mod; if((a&1)==0&&(a&2)==0&&jj) dp[ii][jj][2]=(dp[ii][jj][2]+dp[ii-1][jj-1][a])%mod; if((a&1)==0&&(a&2)&&jj) dp[ii][jj][3]=(dp[ii][jj][3]+dp[ii-1][jj-1][a])%mod; } for(int a=0;a<4;a++) { if((a^(i+j*2))==0)//和初始状态没区别 { real[ii-2][jj]=(real[ii-2][jj]+dp[ii][jj][a])%mod; //if(dp[ii][jj][a]) // int kkk=0; } } //if(i==0&&j==0) // printf("ii %d jj %d dp %d \n",ii,jj,real[ii][jj]); } } } } } int main() { init(); int t; scanf("%d",&t); while(t--) { int n,kk; scanf("%d%d",&n,&kk);// int ans=0; printf("%I64d\n",real [kk]%mod); } return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow
- zoj3605 Find the Marble(三维dp)
- Word Break I,II, Triangle,Palindrome Partitioning 动态规划 DP