HDOJ_1466:n条直线交点数 解题报告

关于动态规划,除了ppt里讲到的把子问题的结果保存起来甭管后面是否用到这个显著特点外,根据我目前粗浅的认识,觉得其解题步骤可以细化为以下几步:

1. 根据题设找到或求出初始条件

    具体如HDOJ_1466求直线交点数这题,设bool p[21][191](最多输入20条直线,对应最多190个交点),当p[i][j]==true时表示i条直线可以有j个交点。(最多输入20条直线,对应最多190个交点)那么p[i][0]==true;是肯定成立的,即全部直线都平行时交点为0。当然p[i][i-1]==true和p[i][2*i-4]==true等也是成立的,不过它们不是向后推倒的必要初始条件,即有p[i][j]==true就足够了。

2. 【核心】找出递推关系,推得全部子问题的答案

    递推方向一般是由简向繁、自底向上。再比如上述的直线交点题:

    m条直线的交点方案数
= (m-r)条平行线与r条直线交叉的交点数 + r条直线本身的交点方案
= (m-r)*r + r条之间本身的交点方案数

    即p[j][k]→p[i][(i-j)*j+k],或者便于理解的形式:p[m+△x][n]→p[m+△x][m*△x+n],其中△x是增加的平行直线数,它们会和原来的m条直线交出m*△x个新交点,再加上原本的n个交点即可。虽然是二维数组,但存在三个变量,故处理时是三重for循环。

3. 输出给定起始条件时的答案

    这个就没啥说的了,注意输出格式别错就行。

HDOJ_1466的具体代码如下:

//HDOJ_1466:输入n(n<=20) 求n条直线的可能相交点数 已知无三条直线交于一点的可能
//利用bool类型的二维数组 其中x表示直线数 y表示交点数 若为true则表示x条直线可以有y个交点

#include <iostream>
using namespace std;
bool p[21][191];
void init()
{
	int i, j, k;
	for( i=1; i<21; i++ )
		p[i][0] = true;
	for( i=2; i<21; i++ )
		for( j=1; j<=i; j++ )
			for( k=0; k<191; k++ )
				if( p[j][k] )
					p[i][(i-j)*j+k] = true;
}/*
  课件中:m条直线的交点方案数
= (m-r)条平行线与r条直线交叉的交点数 + r条直线本身的交点方案
= (m-r)*r + r条之间本身的交点方案数
对应p[i][(i-j)*j+k]=true; 即i=m j=r k=r条直线交点数
*/
int main()
{
	init();
	int i, n, t;
	while( cin >> n )
	{
		t = (n*(n-1))/2;
		for( i=0; i<t; i++ )
			if( p[n][i] )
				cout << i << " ";
		cout << t << endl;
	}
	return 0;
}

你可能感兴趣的:(HDOJ_1466:n条直线交点数 解题报告)