Hdu--1466(DP)

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 }

 

posted @ 2014-11-10 12:24  Naturain  阅读(137)  评论(0编辑  收藏  举报