洛谷打卡Day 8
题目描述
这次期末考试,kkksc03 需要考 4 科。因此要开始刷习题集,每科都有一个习题集,分别有 s1,s2,s3,s4道题目,完成每道题目需要一些时间,可能不等(A1,A2,…,,B1,B2,…,Bs,C1,C2,…,Cs,D1,D2,…,Ds)。
kkksc03 有一个能力,他的左右两个大脑可以同时计算 2 道不同的题目,但是仅限于同一科。因此,kkksc03 必须一科一科的复习。
由于 kkksc03 还急着去处理洛谷的 bug,因此他希望尽快把事情做完,所以他希望知道能够完成复习的最短时间。
输入格式
本题包含 5 行数据:
第 1 行,为四个正整数 s1,s2,s3,s4。
第 2 行,为 A1,A2,…,As共 s1个数,表示第一科习题集每道题目所消耗的时间。
第 3 行,为 B1,B2,…,Bs共 s2个数。
第 4 行,为 C1,C2,…,Cs共 s3个数。
第 5 行,为 D1,D2,…,Ds s4 个数,意思均同上。
输出格式
输出一行,为复习完毕最短时间。
输入输出样例
输入
1 2 1 3
5
4 3
6
2 4 3
输出
20
181
191
313
353
373
383
把题目拆成四个01背包问题,最后求和 每个题两种状态 左脑和右脑 耗时即是背包容量也是价值
看别的大佬的一种思想,当左右脑都为t/2时是最好的。所以当一边的大脑耗时尽量靠近t/2时,另一半的耗时就为解
题解
#include<iostream>
using namespace std;
int a[4];
int work[30];
int dp[21][1201];
int main() {
for (int i = 0; i < 4; i++) cin >> a[i];
int tot = 0;
for (int i = 0; i < 4; i++)
{
int v = 0;
for (int j = 1; j <= a[i]; j++) cin >> work[j], v += work[j];
int t1 = 0;
for (int j = 1; j <= a[i]; j++)
for (int k =0; k <=v/2; k++)
{
if (k < work[j])
dp[j][k] = dp[j - 1][k];
else
dp[j][k] = max(dp[j-1][k], dp[j - 1][k - work[j]] + work[j]);
t1 = max(dp[j][k], t1);
}
tot += max(t1, v - t1);
}
cout << tot << endl;
return 0;
}
题目描述
有 n 根木棒,现在从中选 4 根,想要组成一个正三角形,问有几种选法?
答案对 109+7取模
输入格式
第一行一个整数 n。
第二行 n 个整数,第 i 个整数 ai 代表第 i根木棒的长度。
输出格式
一行一个整数代表答案。
输入输出样例
输入
4
1 1 2 2
输出
1
桶排序
https://blog.csdn.net/bqw18744018044/article/details/81738883
用到了桶,记录每个长度出现的次数,桶的编号即为木棍长度
然后遍历,去找两个相同长度的木棍(两种情况)
**二进制位移操作 >>1 等价于 /2 **
** <<1 等价于 *2 **
对x取模 = %x
题解
#include<bits/stdc++.h>
#define ll long long
#define MOD 1000000007LL
using namespace std;
ll b[5044];
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
int x;
cin>>x;
b[x]++;
}
ll ans=0;
for(int i=1;i<=5000;++i)
{
for(int j=i;j<=5000;++j)
{
if(i+j>5000)
break;
if(i==j)
{
if(b[i]>=2&&b[i<<1]>=2)
ans=(ans+(b[i]*(b[i]-1)/2%MOD*(b[i<<1]*(b[i<<1]-1)/2)%MOD))%MOD;
}else{
if(b[i]>=1&&b[j]>=1&&b[i+j]>=2)
ans=(ans+(b[i]*b[j]%MOD*(b[i+j]*(b[i+j]-1)/2)%MOD))%MOD;
}
}
}
cout<<ans;
return 0;
}

浙公网安备 33010602011771号