POJ1018
分类是DP,可是却用暴力枚举过了,继续找思路。。。
下面是纯暴力:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #define MAX(a,b) (a) > (b)? (a):(b) 6 #define MIN(a,b) (a) < (b)? (a):(b) 7 #define mem(a) mem(a,0,sizeof(a)) 8 #define INF 1000000007 9 #define MAXN 105 10 using namespace std; 11 12 int T,N,B[MAXN][MAXN],P[MAXN][MAXN],num[MAXN]; 13 14 int find_ans(int a,int b) 15 { 16 int i,j,key = B[a][b],Min; 17 int ans = 0; 18 for(i = 0; i < N; i ++) 19 { 20 Min = INF; 21 for(j = 0; j < num[i]; j++) 22 { 23 if(B[i][j] >= key) 24 Min = MIN(Min,P[i][j]); 25 } 26 ans += Min; 27 } 28 return ans; 29 } 30 31 32 int main() 33 { 34 int i, j; 35 while(~scanf("%d",&T))while(T--) 36 { 37 scanf("%d",&N); 38 for(i = 0; i < N; i ++ ) 39 { 40 scanf("%d",&num[i]); 41 for(j = 0; j < num[i]; j ++) 42 { 43 scanf("%d%d",&B[i][j],&P[i][j]); 44 #ifdef KengDie 45 MaxB = MAX(B[i][j],MaxB); 46 #endif 47 } 48 } 49 double ans = 0; 50 for(i = 0; i < N; i ++ ) 51 { 52 for(j = 0;j < num[i]; j ++) 53 { 54 ans = MAX(ans, (double)B[i][j]/(double)find_ans(i,j)); 55 } 56 } 57 printf("%.3lf\n", ans); 58 } 59 return 0; 60 }
然后是暴力加了一点点的优化了的,虽然没有提高多少,似乎时间就没有提高=.=!
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #define MAX(a,b) (a) > (b)? (a):(b) 6 #define MIN(a,b) (a) < (b)? (a):(b) 7 #define mem(a) mem(a,0,sizeof(a)) 8 #define INF 1000000007 9 #define MAXN 105 10 using namespace std; 11 12 int T,N,B[MAXN][MAXN],P[MAXN][MAXN],num[MAXN]; 13 14 int find_ans(int a,int b) 15 { 16 int i,j,key = B[a][b],Min; 17 int ans = 0; 18 for(i = 0; i < N; i ++) 19 { 20 Min = INF; 21 for(j = 0; j < num[i]; j++) 22 { 23 if(B[i][j] >= key) 24 Min = MIN(Min,P[i][j]); 25 } 26 ans += Min; 27 } 28 return ans; 29 } 30 31 32 int main() 33 { 34 int i, j; 35 while(~scanf("%d",&T))while(T--) 36 { 37 scanf("%d",&N); 38 int Min_max = INF; 39 for(i = 0; i < N; i ++ ) 40 { 41 scanf("%d",&num[i]); 42 int MaxB = -INF; 43 for(j = 0; j < num[i]; j ++) 44 { 45 scanf("%d%d",&B[i][j],&P[i][j]); 46 MaxB = MAX(B[i][j],MaxB);//找到每一行的最大值 47 } 48 Min_max = MIN(Min_max,MaxB);//找到所有行最大值的最小值 49 } 50 double ans = 0; 51 for(i = 0; i < N; i ++ ) 52 { 53 for(j = 0;j < num[i]; j ++) 54 { 55 if(B[i][j] > Min_max)continue;//如果比所有行的最大值的最小值大,就直接跳出 56 ans = MAX(ans, (double)B[i][j]/(double)find_ans(i,j)); 57 } 58 } 59 printf("%.3lf\n", ans); 60 } 61 return 0; 62 }
然后再网上找到了数据源
输入: http://sina.sharif.edu/~acmicpc/acmicpc02/inipc/probs/C.IN
输出: http://sina.sharif.edu/~acmicpc/acmicpc02/inipc/probs/C.OUT
发现所有的B值都小于1000,所以钻个空子,用DP[100][1000]就可以了
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <iostream> 5 #define MAX(a,b) (a) > (b)? (a):(b) 6 #define MIN(a,b) (a) < (b)? (a):(b) 7 #define mem(a) mem(a,0,sizeof(a)) 8 #define INF 1000000007 9 #define MAXN 105 10 #define MAXC 1005 11 using namespace std; 12 int DP[MAXN][MAXC]; 13 int main() 14 { 15 int T; 16 while(~scanf("%d",&T))while(T--) 17 { 18 int N,i,j,k,B[MAXN]={0},P,m; 19 double ans = 0; 20 scanf("%d",&N); 21 for(i = 0;i <= 100;i ++) 22 { 23 for(j = 0; j <= 1000; j ++) 24 { 25 DP[i][j] = INF; 26 } 27 } 28 for(i = 1; i <= N; i ++) 29 { 30 scanf("%d",&m); 31 for(j = 1; j <= m; j ++) 32 { 33 scanf("%d%d",&B[j],&P); 34 if(i == 1) 35 { 36 DP[i][B[j]] = P; 37 if(N == 1)ans = MAX(ans,(double)B[j]/(double)P); 38 continue; 39 } 40 for(k = 1; k <= 1000; k++)if(DP[i-1][k] != INF) 41 { 42 int key = MIN(k,B[j]); 43 DP[i][key] = MIN(DP[i][key],DP[i-1][k]+P); 44 if(i == N) 45 { 46 ans = MAX(ans,(double)key/(double)DP[i][key]); 47 } 48 } 49 } 50 } 51 printf("%.3lf\n",ans); 52 53 } 54 return 0; 55 }