C - Sentou
Time Limit: 2 sec / Memory Limit: 256 MB
Score : 300300 points
Problem Statement
In a public bath, there is a shower which emits water for TT seconds when the switch is pushed.
If the switch is pushed when the shower is already emitting water, from that moment it will be emitting water for TT seconds. Note that it does not mean that the shower emits water for TT additional seconds.
NN people will push the switch while passing by the shower. The ii-th person will push the switch titi seconds after the first person pushes it.
How long will the shower emit water in total?
Constraints
- 1≤N≤200,0001≤N≤200,000
- 1≤T≤1091≤T≤109
- 0=t1<t2<t3<,...,<tN−1<tN≤1090=t1<t2<t3<,...,<tN−1<tN≤109
- TT and each titi are integers.
Input
Input is given from Standard Input in the following format:
NN TT
t1t1 t2t2 ... tNtN
Output
Assume that the shower will emit water for a total of XX seconds. Print XX.
Sample Input 1 Copy
Copy
2 4
0 3
Sample Output 1 Copy
Copy
7
Three seconds after the first person pushes the water, the switch is pushed again and the shower emits water for four more seconds, for a total of seven seconds.
Sample Input 2 Copy
Copy
2 4
0 5
Sample Output 2 Copy
Copy
8
One second after the shower stops emission of water triggered by the first person, the switch is pushed again.
Sample Input 3 Copy
Copy
4 1000000000
0 1000 1000000 1000000000
Sample Output 3 Copy
Copy
2000000000
Sample Input 4 Copy
Copy
1 1
0
Sample Output 4 Copy
Copy
1
Sample Input 5 Copy
Copy
9 10
0 3 5 7 100 110 200 300 311
Sample Output 5 Copy
Copy
67
题意:
n个人,每一个人在t[i]的时间拧开水龙头,拧开一次水会流T时间,问水流的时间。
分析:
min(T,t
#include<bits/stdc++.h>
using namespace std;
const int N=200500;
typedef long long ll;
int t[N];
int n,m;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%d",&t[i]);
}
ll ans=0;
ll sum=0;
for(int i=2; i<=n; i++)
{
ans+=min(t[i]-t[i-1],m);
}
cout<<ans+m<<endl;
return 0;
}
D - Simple Knapsack
Time Limit: 2 sec / Memory Limit: 256 MB
Score : 400400 points
Problem Statement
You have NN items and a bag of strength WW. The ii-th item has a weight of wiwi and a value of vivi.
You will select some of the items and put them in the bag. Here, the total weight of the selected items needs to be at most WW.
Your objective is to maximize the total value of the selected items.
Constraints
- 1≤N≤1001≤N≤100
- 1≤W≤1091≤W≤109
- 1≤wi≤1091≤wi≤109
- For each i=2,3,...,Ni=2,3,...,N, w1≤wi≤w1+3w1≤wi≤w1+3.
- 1≤vi≤1071≤vi≤107
- WW, each wiwi and vivi are integers.
Input
Input is given from Standard Input in the following format:
NN WW w1w1 v1v1 w2w2 v2v2 : wNwN vNvN
Output
Print the maximum possible total value of the selected items.
Sample Input 1 Copy
Copy
4 6 2 1 3 4 4 10 3 4
Sample Output 1 Copy
Copy
11
The first and third items should be selected.
Sample Input 2 Copy
Copy
4 6 2 1 3 7 4 10 3 6
Sample Output 2 Copy
Copy
13
The second and fourth items should be selected.
Sample Input 3 Copy
Copy
4 10 1 100 1 100 1 100 1 100
Sample Output 3 Copy
Copy
400
You can take everything.
Sample Input 4 Copy
Copy
4 1 10 100 10 100 10 100 10 100
Sample Output 4 Copy
Copy
0
You can take nothing.
题意:
你有N个物品和容量为W的背包,每个物品要么选要么不选,它们的体积为wi,价值为vi,求总体积至多为W情况下能拿走物品价值的最大值。
分析:
但这题的体积只有四种,所以暴力能过
还有一种神仙DP
#include<bits/stdc++.h>
typedef long long LL;
const int MaxN = 101;
LL N,W;
LL w[MaxN], v[MaxN];
LL DP[MaxN][4*MaxN][MaxN];
void solve()
{
LL W1 = w[1];
for(int i=1;i<=N;i++)
w[i] = w[i] - W1;
for(int i=1;i<=N;i++)
{
for(int j=0;j<=300;j++)
{
for(int k=1;k<=N;k++)
{
if( j >= w[i] )
DP[i][j][k] =std::max(DP[i-1][j][k], DP[i-1][j-w[i]][k-1]+v[i]);
else
DP[i][j][k] = DP[i-1][j][k];
}
}
}
LL ans = 0;
for(int j=0;j<=300;j++)
{
for(int k=0;k<=N;k++)
{
if( k*W1+j<=W)
{
ans = std::max(ans, DP[N][j][k]);
}
}
}
printf("%lld\n", ans);
}
int main()
{
scanf("%lld%lld", &N, &W);
for(int i=1;i<=N;i++) scanf("%lld%lld", &w[i], &v[i]);
solve();
}