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);
}
posted @ 2024-09-23 22:14  Kevinhwbb  阅读(6)  评论(0编辑  收藏  举报