动态规划(DP计数):HDU 5116 Everlasting L

Matt loves letter L.

A point set P is (a, b)-L if and only if there exists x, y satisfying:

P = {(x, y), (x + 1, y), . . . , (x + a, y), (x, y + 1), . . . , (x, y + b)}(a, b ≥ 1)

A point set Q is good if and only if Q is an (a, b)-L set and gcd(a, b) = 1.

Matt is given a point set S. Please help him find the number of ordered pairs of sets (A, B) such that:

Input

The first line contains only one integer T , which indicates the number of test cases.

For each test case, the first line contains an integer N (0 ≤ N ≤ 40000), indicating the size of the point set S.

Each of the following N lines contains two integers xi, yi, indicating the i-th point in S (1 ≤ xi, yi ≤ 200). It’s guaranteed that all (xi, yi) would be distinct.

Output

For each test case, output a single line “Case #x: y”, where x is the case number (starting from 1) and y is the number of pairs.

Sample Input

2
6
1 1
1 2
2 1
3 3
3 4
4 3
9
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3

Sample Output

Case #1: 2
Case #2: 6

Hint

n the second sample, the ordered pairs of sets Matt can choose are: A = {(1, 1), (1, 2), (1, 3), (2, 1)} and B = {(2, 2), (2, 3), (3, 2)} A = {(2, 2), (2, 3), (3, 2)} and B = {(1, 1), (1, 2), (1, 3), (2, 1)} A = {(1, 1), (1, 2), (2, 1), (3, 1)} and B = {(2, 2), (2, 3), (3, 2)} A = {(2, 2), (2, 3), (3, 2)} and B = {(1, 1), (1, 2), (2, 1), (3, 1)} A = {(1, 1), (1, 2), (2, 1)} and B = {(2, 2), (2, 3), (3, 2)} A = {(2, 2), (2, 3), (3, 2)} and B = {(1, 1), (1, 2), (2, 1)} Hence, the answer is 6.

  这道题DP计数,十分有意义。

  dp[i][j]:表示a∈[1,i],b∈[1,j],sigma(a,b)==1

  sum[i][j]:表示竖直部分穿过点(i,j)的L的个数

  看代码就能懂了……

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=210;
typedef long long LL;
LL map[N][N],st[N],S,M;
LL f[N][N],dp[N][N],sum[N][N];
/*f[i][j]:[1,j]中与i互质的数的个数*/
LL dwn[N][N],rht[N][N];int T,cas,k,x,y;
LL Gcd(LL a,LL b){return b?Gcd(b,a%b):a;}
void Prepare(){
    for(int i=1;i<=200;i++)
        for(int j=1;j<=200;j++){
            f[i][j]=f[i][j-1]+(Gcd(i,j)==1);
            dp[i][j]=dp[i-1][j]+f[i][j];
        }
}
void Init(){S=M=0;
    memset(map,0,sizeof(map));
    memset(sum,0,sizeof(sum));
    memset(dwn,0,sizeof(dwn));
    memset(rht,0,sizeof(rht));
}
int main(){
    Prepare();
    scanf("%d",&T);
    while(T--){
        Init();scanf("%d",&k);
        while(k--){scanf("%d%d",&x,&y);map[x][y]=1;}
        for(int i=200;i>=1;i--)
            for(int j=200;j>=1;j--){
                if(!map[i][j])continue;
                if(map[i+1][j])dwn[i][j]=dwn[i+1][j]+1;
                if(map[i][j+1])rht[i][j]=rht[i][j+1]+1;
            }

        for(int i=1;i<=200;i++)
            for(int j=1;j<=200;j++){
                if(!map[i][j])continue;
                memset(st,0,sizeof(st));
                for(int k=1;k<=dwn[i][j];k++)
                    st[k]=f[k][rht[i][j]];
                for(int k=dwn[i][j];k>=1;k--)
                    st[k-1]+=st[k];
                for(int k=0;k<=dwn[i][j];k++)
                    sum[i+k][j]+=st[k];
                S+=st[0];
            }

        for(int i=1;i<=200;i++)
            for(int j=1;j<=200;j++){
                if(!dwn[i][j])continue;
                if(!rht[i][j])continue;
                LL tot=dp[dwn[i][j]][rht[i][j]];
                LL calc=sum[i][j]-tot;
                for(int k=1;k<=rht[i][j];k++){
                    calc+=sum[i][j+k];
                    M+=2*calc*f[k][dwn[i][j]];
                }
                M+=tot*tot;
            }
        printf("Case #%d: %lld\n",++cas,S*S-M);
    }
    return 0;
}
时间: 2024-10-19 23:15:01

动态规划(DP计数):HDU 5116 Everlasting L的相关文章

HDU 5116 Everlasting L

题意:给定若干个整数点,若一个点集满足P = {(x, y), (x + 1, y), . . . , (x + a, y), (x, y + 1), . . . , (x, y + b)}(a, b ≥ 1)  且 gcd(a, b)==1 则称这是一个好(a, b)-L集.求共有多少个(A, B)满足A,B都是好L集且A,B不相交. 思路是先找出好L集的数量a,再找出相交的好L集对数b,则答案为a * a - b . 首先要解决的第一个问题是求出a,一个自然的思路是对于每个点,分别向右.向下

HDU 4055 The King’s Ups and Downs(DP计数)

题意:国王的士兵有n个,每个人的身高都不同,国王要将他们排列,必须一高一矮间隔进行,即其中的一个人必须同时高于(或低于)左边和右边.问可能的排列数.例子有1千个,但是最多只算到20个士兵,并且20个的情况的答案已给出. 思路:是此题HDU 4055 Number String(DP计数) 的简单版,所以看此题解就行了.数量较小,可以预先算出来.要同时考虑 <><>和><><这样的两种情况. 1 #include <iostream> 2 #inc

ZOJ3380- Patchouli&#39;s Spell Cards(概率DP+计数)

Patchouli's Spell Cards Time Limit: 7 Seconds      Memory Limit: 65536 KB Patchouli Knowledge, the unmoving great library, is a magician who has settled down in the Scarlet Devil Mansion (紅魔館). Her specialty is elemental magic employing the seven ele

【插头DP】HDU 1964 Pipes

通道:http://acm.hdu.edu.cn/showproblem.php?pid=1964 题意:单回路,权值,无阻碍. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAX_N = 13; 8 const int MAX_M = 13; 9 const int HASH = 10007; 10

【插头DP】HDU 1693 Eat the Trees

通道:http://acm.hdu.edu.cn/showproblem.php?pid=1693 题意:多回路路径方案数,无障碍. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 7 const int MAX_N = 13; 8 const int MAX_M = 13; 9 const int HASH = 10007; 1

hdu2571 命运 动态规划Dp

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2571 Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了! 可谁能想到,yifenfei在斩杀了一些虾兵蟹将后,却再次面临命运大迷宫的考验,这是魔王lemon设下的又一个机关.要知道,不论何人,若在迷宫中被困1小时以上,则必死无疑! 可怜的yifenfei为了去救MM,义无返顾地跳进了

Fibonacci斐波拉契数列----------动态规划DP

n==10 20 30 40 50 46 体验一下,感受一下,运行时间 #include <stdio.h>int fib(int n){ if (n<=1)     return 1; else            return fib(n-1)+fib(n-2); }int main( ){ int n; scanf("%d",&n); printf("%d\n" ,fib(n) );} 先 n==10 20 30 40 50 46

动态规划(DP),类似LIS,FatMouse&#39;s Speed

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1108 解题报告: 1.首先按照weight从小到大排列,weight相同的按照speed从大到小排列; 2.Count[i]表示到第i个老鼠时,所求的最长“速度递减”子序列的长度: 3.path[i]=j是题目的关键,记录在Count[i]=Count[j]时,即最长“速度递减”子序列最后一个老鼠的前一只老鼠的位置 4.递归输出id void output(in

(RQoj 15 采药------rwkj 10.1.5.253 1447) 动态规划 DP 1

#include <iostream>#include <string.h>using namespace std;int dp[105][1005], w[105],v[105],T,M;int max(int x,int y){ return x>y?x:y; } void f( ){ int i,j; for (i=1; i<=M; i++) for (j=0;j<=T; j++) { if (i==0) dp[i][j]=0; else dp[i][j]=