2024.9.23
今日总结:
今天写文化课作业写的时间有点长锁业只写了两道题
1:Split and Insert
这道题主要是一道状压的题目动态转移方程
点击查看代码
#include<bits/stdc++.h>
using namespace std;
const long long INF = 1e16;
const int N = 1e6 + 10;
typedef long long ll;
int n,m;
int a[N],b[N],c[N];
ll dp[110][110][110];
int main()
{
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i ++)
scanf("%d",&c[i]);
for(int i = 1;i <= n;i ++)
scanf("%d",&a[i]);
for(int i = 1;i <= n;i ++)
b[a[i]] = i;
reverse(c + 1,c + m + 1);
memset(dp,520 / 2,sizeof(dp));
for(int i = 1;i <= n;i ++)
{
for(int j = i;j <= n;j ++)
{
if(i != j && b[j] < b[j - 1]) break;
dp[0][i][j] = 0;
}
}
for(int p = 1;p <= m;p ++)
{
for(int i = 1;i <= n;i ++)
for(int j = i;j <= n;j ++)
dp[p][i][j] = dp[p - 1][i][j];
for(int i = 1;i <= n;i ++)
for(int j = i;j <= n;j ++)
for(int k = j + 1;k <= n;k ++)
dp[p][i][k] = min(dp[p][i][k],dp[p - 1][i][j] + dp[p - 1][j + 1][k] + (ll)c[p] * (k - j));
}
printf("%lld\n",dp[m][1][n] > INF ? -1 : dp[m][1][n]);
return 0;
}
2:Damage over Time
这道题主要是需要统计前缀最大值和后缀最大值,
最后用二分答案和用贪心的思想求出可以打出的最大伤害
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const int N = 3e5 + 10;
int n,m;
int a[N];
ll h;
ll Find(ll x1,ll x2,ll x3,ll y)
{
if(x2 > x1) return 0;
-- x2;
ll tmp = max(0ll,x1 - x3) * x3 + min(x1,x3) * (min(x1,x3) + 1) / 2 - max(0ll,x2 - x3) * x3 - min(x2,x3) * (min(x2,x3) + 1) / 2;
if(tmp > h / y) return h;
return tmp * y;
}
vector<pair<ll,ll>>v1,v,v2;
bool Check(ll x)
{
v.clear();
v1.clear();
ll Max = 0;
for(auto it : v2)
{
it.first = min(it.first, x);
if(it.first * it.second > Max)
{
v1.push_back(it);
Max = it.first * it.second;
}
}
ll ans = 0;
reverse(v1.begin(),v1.end());
v.push_back(*v1.begin());
for(int i = 1;i < v1.size();i ++)
if(v1[i].second > v.back().second) v.push_back(v1[i]);
ll pa = x;
for(int i = 0;i < v.size();i ++)
{
if(i + 1 == v.size())
{
ans += Find(pa,1,v[i].first,v[i].second);
break;
}
ll tmp = (v[i + 1].second * v[i + 1].first + v[i].second - 1) / v[i].second;
ans += Find(pa,tmp,v[i].first,v[i].second);
pa = tmp - 1;
if(ans >= h) return 1;
}
return ans >= h;
}
int main()
{
scanf("%d%lld",&n,&h);
ll x,y,id = h;
for(int i = 0;i < n;i ++)
{
scanf("%lld%lld",&x,&y);
v2.push_back(make_pair(x, y));
id = min(id,x + ((h + x - 1) / x - (x + 1) / 2 * y + y - 1) / (y));
}
sort(v2.begin(),v2.end());
ll st = 1,mid;
while(st < id)
{
mid = (st + id) / 2;
if(Check(mid))
id = mid;
else st = mid + 1;
}
printf("%lld\n",id);
}