2014-11-10 12:15:40
思路:挺好的思维,DP来做。
现在考虑n条直线,假设1,2,3...n-1条直线的情况都已算完,设n条直线里有有n-r条直线互相平行,那么另外r条直线与这n-r条直线交点数:(n-r)*r,然后还要加上算r条直线的方案,也就是f(n) = (n-r)*r + f(r),(1<=r<n),用dp[i][j]来记录i条直线j个交点是否可行。
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Mon 10 Nov 2014 11:44:43 AM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 27 int n; 28 int dp[21][210]; 29 30 int main(){ 31 memset(dp,0,sizeof(dp)); 32 for(int i = 0; i <= 20; ++i) 33 dp[i][0] = 1; 34 for(int i = 1; i <= 20; ++i){ 35 for(int r = 1; r < i; ++r){ 36 for(int j = 0; j <= 200; ++j){ 37 if(dp[r][j]){ 38 dp[i][(i - r) * r + j] = 1; 39 } 40 } 41 } 42 } 43 while(scanf("%d",&n) != EOF){ 44 printf("0"); 45 for(int i = 1; i <= 200; ++i) if(dp[n][i]) 46 printf(" %d",i); 47 puts(""); 48 } 49 return 0; 50 }