天天看点

UVa:10910 Marks Distribution

一开始感觉可以用计数类的dp,但是自己推了推发现了个规律,于是写了一个。。。

不知道为什么只有1门课而且P小于T的时候是1为什么不是0。。(后来发现了,P是及格线,T是它的得分,问的是有多少种可能。。)

后来在网上看见果然可以用计数类的dp来递推:

首先问题可以转换成用i个数,组成和为j的种类,dp[i][j]。然后状态转移方程dp[i][j] = dp[i - 1][j] + dp[i][j - 1], 就是无非在dp[i - 1][j]的基础上每个后面加个0,以及dp[i][j - 1]的基础上在第一个数上加1.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define ll long long
#define INF 2139062143
#define MAXN 100005
using namespace std;
int main()
{
    int T;
    //freopen("outttt.txt","w",stdout);
    scanf("%d",&T);
    while(T--)
    {
        int n,t,p;
        scanf("%d%d%d",&n,&t,&p);
        int v=t-n*p;
        if(v<0) printf("0\n");
        else if(n==1)  printf("1\n");
        else
        {
            int arr[100]= {0};
            v++;
            for(int i=1; i<=v; ++i)
                arr[i]=1;
            int d=n-1;
            for(int i=1; i<d; ++i)
            {
                for(int j=1; j<=v; ++j)
                    arr[j]=arr[j-1]+arr[j];
            }
            int sum=0;
            for(int i=1; i<=v; ++i)
                sum+=arr[i];
            printf("%d\n",sum);
        }
    }
    return 0;
}