[hdu2156]分数矩阵

Problem Description
我们定义如下矩阵:
1/1 1/2 1/3
1/2 1/1 1/2
1/3 1/2 1/1
矩阵对角线上的元素始终是1/1,对角线两边分数的分母逐个递增。
请求出这个矩阵的总和。
 

 

Input
每行给定整数N (N<50000),表示矩阵为 N*N.当N为0时,输入结束。
 

 

Output
输出答案,保留2位小数。
 

 

Sample Input
1
2
3
4
0
 

 

Sample Output
1.00
3.00
5.67
8.83
 
 
一看,大水题,马上来了个循环,然后计算 n/2的,得到复杂度O(n/2*n),提上去发现,TLE...我靠!
然后想了想,发现这题可以dp过去.恩....这下子肯定可以过了吧!!!?
 
dp的过程如下图:
n==2时:
1/1 1/2             
1/2 1/1   
n==3时:
1/1 1/2 1/3
1/2 1/1 1/2
1/3 1/2 1/1
 
容易看出
n==3时,dp[3] = dp[2] - dp[1] + dp[2] + 2*(1/n)
化简一下,推导出:
dp[n]=2*dp[n-1]-do[n-2] + (2/n)
 
接着快速的敲了Java代码,过了样例,提上去..一个大大的WA!!!!!!!!!!!!!!!!
然后把float改成了double,发现居然是两个不同的答案,再提交一次,还是WA.....(无奈,需要去恶补一下Java的浮点运算)
 
然后很无奈的换C敲一遍.....就AC了.....无奈无奈无奈
C Code:
#include <stdio.h>
double dp[50001];
int main(){
    int n;
      dp[1]=1;
      dp[2]=3;
      
      for(int i=3;i<=50000;i++){
          dp[ i ] = 2 * dp[ i - 1 ] - dp[ i - 2 ] + ( 2.0 / i );
    }
    while(scanf("%d",&n)==1 && n){
        printf("%.2lf\n",dp[n]);
    }
}

 

顺便给上Java的 WA code:
 
import java.util.Scanner;

public class Main {

    public static double[] dp = new double[ 50001 ];

    public static void dp() {
        dp[ 1 ] = 1;
        dp[ 2 ] = 3;
        for( int i = 3; i <= 50000; i++ ) {
            dp[ i ] = 2 * dp[ i - 1 ] - dp[ i - 2 ] + ( 2.0 / i );
        }
    }

    public static void main( String[] args ) {
        Scanner sc = new Scanner( System.in );
        dp();
        while( sc.hasNext() ) {
            int n = sc.nextInt();
            if( n == 0 )
                return;
            else {
                System.out.printf( "%.2f\n", dp[ n ] );
            }
        }
    }
}

求Java老司机讲解下为何卡浮点呀。。。。

 
 
 
 
 
 
 
posted @ 2016-06-12 17:51  hudiwei-hdw  阅读(220)  评论(0编辑  收藏  举报