2 条题解

  • 1
    @ 2024-7-23 23:25:28

    啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

    啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊

    我赛时一眼看到DP !

    然后打了一个三维DP !

    考虑滚动数组,然后我就一直调啊调。。。

    没调出来!!!

    反倒70 -->20 了!!!

    啊啊啊啊啊啊啊啊

    怕 MLE 所以数组开小了点,但是没想到根本没用!开大了还能拿40!

    我只有20!!!!

    啊啊啊啊啊啊啊啊啊啊啊啊!

    啊啊啊啊啊啊啊啊啊啊啊!

    啊啊啊啊啊啊啊啊啊啊啊!

    啊啊啊啊啊啊啊啊啊啊啊!!

    啊啊啊啊啊啊啊啊啊啊啊!!!!

    (这里安葬着一位一打比赛就掉链子的小蒟蒻

    更气人的是,赛后立马就调出来了!

    现在的我已经想sha人了((((

    啊啊啊啊啊啊!!!

    1. 三维DP,开小数组:20pts
    2. 三维DP,开大数组:70pts
    3. 压维变二维DP,避开所有坑点:100pts

    AC CODE

    //t2
    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    
    const int N=1e3+10;
    int n,t,m,p,a[N];
    int dp[N][N];
    
    signed main()
    {
    	scanf("%lld%lld%lld%lld",&n,&t,&m,&p);
    	for(int i=1;i<=n;++i)
    	{
    		scanf("%lld",&a[i]);
    	}
    	dp[0][0]=1;
    	for(int i=1;i<=n;++i)//枚举工人 
    	{
    		for(int j=m;j>=0;--j)//枚举失误数 
    		{
    			for(int k=t;k>=0;--k)//零件 
    			{
    				for(int l=1/*从1开始*/; l<=k && l*a[i]<=j ;++l)//枚举此工人做多少零件
    				{
    					dp[j][k]+=dp[j-l*a[i]][k-l];
    					dp[j][k]%=p;
    				}
    			}
    		}
    	}
    	
    	int ans=0;
    	for(int i=0;i<=m;++i)//从0开始
    	{
    //		cout<<dp[i][t]<<" ";
    		ans+=dp[i][t];
    		ans%=p;
    	}
    	printf("%lld",ans);
    	
    	return 0;
    }
    

    唉。。。

    死吧。

    • 0
      @ 2024-7-24 15:52:18

      题目等价于:现在有一个体积为 QQ 的背包,有 NN 个物品,第 ii 个物品的体积为 aia_i 有无限个。要求在这 NN 个物品中取恰好 KK 个物品,背包能装下的方案有多少种,答案对 PP 取模。

      dp[i][j][k]dp[i][j][k] 表示前 ii 个物品,恰好取 jj 个取到体积为 kk 的方案数。

      完全背包板子:dp[i][j][k]=dp[i][j][k]+dp[i][j1][ka[i]]dp[i][j][k]=dp[i][j][k]+dp[i][j-1][k-a[i]]

      状态压缩一下,时间复杂度 O(N×K×Q)O(N \times K \times Q)

      • 1

      信息

      ID
      3089
      时间
      3000ms
      内存
      256MiB
      难度
      8
      标签
      (无)
      递交数
      61
      已通过
      10
      上传者