积分大小 | ||||||
| ||||||
Description | ||||||
暑期集训开始了,集训队里有N个人,每个人有一定的积分值,每个人等积分可能相等也可能不等,那一共有多少种积分大小的可能呢? 例如,N==2,那么有可能第一个人比第二个人积分高,有可能俩人积分相等,有可能第二个人比第一个人积分高,一共三种可能。 | ||||||
Input | ||||||
每组数据第一行1个整数N,代表有N个人(1≤N<19) | ||||||
Output | ||||||
对于每组数据输出一个整数占一行,代表N人之间的积分大小有多少种可能。 | ||||||
Sample Input | ||||||
2 3 | ||||||
Sample Output | ||||||
3 13 | ||||||
Hint | ||||||
n == 3, 假设三人积分分别是a,b,c,那么有如下关系 a=b=c,a>b=c,a>b>c,a>c>b,a=b>c,a=c>b,b>a>c,b>c>a,b=c>a,b>a=c,c>a>b,c>b>a,c>b=a,共13种。 | ||||||
Source | ||||||
2014暑假集训练习赛(8月6日) |
题意不解释
dp【i】【j】
i 个人 j代表不相同的积分个数
dp【i】的值通过对dp【i-1】分析得来
dp[i-1][ j ]*j代表从上一个状态中任选一个数使得新加入的数相等
dp[i-1][j-1]*j代表从上一个状态中插空的个数 (因为新加入的数不同于以前的j-1个)有j个空
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll long long
ll dp[103][133];
ll res[33];
/// i 代表总人数 j 代表不同的成绩出现的数量 like 2 2 3 (j==2)
/// dp[i]的数值由本来的dp[i-1]决定
///没多增加一个人 所有的状态等于上一个状态*人数(可插入的人数)
int main()
{
for(int i=1; i<19; i++)
dp[i][1]=1;
for(int i=2; i<19; i++)
{
for(int j=2; j<19; j++)
{
dp[i][j]=dp[i-1][j]*j+dp[i-1][j-1]*j;
}
}
for(int i=1; i<19; i++)
{
for(int j=1; j<=i; j++)
res[i]+=dp[i][j];
}
int n;
while(~scanf("%d",&n))
{
printf("%lld\n",res[n]);
}
}