題目描述:
學校裡有n個同學,老師要按照同學們的考試成績給大家進行排名,一共有多少種不同的排名可能(成績相同的同學不計名字次序,算一種排名)。
輸入描述:
每組資料第一行乙個整數n,代表有n同學(1 <= n <= 19)。
輸出描述:
對於每組資料輸出乙個整數佔一行,代表n個同學之間的排名有多少種可能。
例子:輸入23
輸出313舉例:
當n為2時,一共3種排名;當n為3時,一共13種排名。
思路一:遞迴法
假設n個人,排出了m個名次,有f(n,m)種結果(1<=m<=n)
當m=1時,f(n,m)=1;
當m<1或m>n時,f(n,m)=0;
當1n||m<1時,f(n,m)=0;
當1==m時,f(n,m) = 1;
當1using namespace std;
long long computing(int n, int m)
}int main()
cout << sum << endl;
} return 0;
}思路二:動態規劃
利用dp[i][j]表示有i個人,j種名次。那麼顯然有如下關係成立:
當i=j時,dp[i][j] = j!
當j=1時,dp[i][j] = 1
當i>j>1時,dp[i][j] = dp[i-1][j] * j + dp[i-1][j-1] * j
第一條是沒有成績並列的情況,直接全排列;
第二條是成績全部相等,顯然只有1種;
第三條是狀態轉移方程:當i-1個人排完名次之後加入乙個人,有兩種情況:
他和某乙個或幾個人並列,這種情況下之前就已經有j個排名了,他可能和這種中的任何一種並列;
他有乙個新的名次,這種情況相當於他在j個空檔中選擇乙個,有j種可能。
而答案就是dp[i][j]對j求和。
核心**如下:
#include using namespace std;
long long dp[19][19]; //i個人排j個名次
long long computing(int n)
//當i=j時,dp[i][j] = j!
//當j=1時,dp[i][j] = 1
//當i>j>1時,dp[i][j] = dp[i-1][j] * j + dp[i-1][j-1] * j
long long solve(int n)
} for(int i = 1; i <= n; i++)
return sum;
}int main()
return 0;
}
核心**2如下:
#include #include #include using namespace std;
int computing(int n)
int main()
} while(scanf("%d", &n) != eof)
cout << sum << endl;
} return 0;
}
期末考試成績
劃分方法如下,90分 含90 以上的為a,8090 含80 間的為b,7080 含70 間的為c,60 70 含60 的為d,不及格的為e。根據輸入的成績,程式設計輸出各個級別段人數。input 輸入第一行包含乙個正整數n n 100 代表學生的數目,接下來有n行資料每行乙個整數 0 100 代表 ...
對學員的結業考試成績評測(用Switch來寫)
對學員的結業考試成績評測 用switch來寫 score 90 a 80 score 90 b 70 score 80 c 60 score 70 d score 60 e using system console.readline 編寫 現的一些問題 剛開始在case後面寫了乙個比較運算子,結果程...
PAT考試乙級1004之成績排名
題目 讀入 n 0 名學生的姓名 學號 成績,分別輸出成績最高和成績最低學生的姓名和學號。輸入格式 每個測試輸入包含 1 個測試用例,格式為 第 1 行 正整數 n 第 2 行 第 1 個學生的姓名 學號 成績 第 3 行 第 2 個學生的姓名 學號 成績 第 n 1 行 第 n 個學生的姓名 學號...