19の那天,祂跳过了18,变成了橙廿刃

标题党标题党标题党标题党标题党标题党标题党标题党标题党标题党
如图:

image

同分の肝硬化

image

2025.08.10模拟赛赛后牢骚总结&&题解

T1 CF1919C Grouping Increases

洛谷 CF1919C Grouping Increases

image

赛时部分分:10pts

dfs深度优先搜索

预处理

输入数组\(a[ ]\);

\(a[0]\)\(ans\)(即记录答案的变量)赋值为极大值 INT_MAX

记录一个\(sum[i]\),代表将前i个元素放到同一个子序列中获得的惩罚值,也可定义为一个前缀和数组,对于 \(sum[i]\) 来说:

  • 如果 \(a[i+1]>a[i]\) ,则\(sum[i]=sum[i-1]+1\) ;
  • 如果 \(a[i+1]\leq a[i]\) ,则\(sum[i]=sum[i-1]\) ;

DFS

  1. 参数一:\(x\) ,即下一次要搜索\(a[x]\)

  2. 参数二:\(last\),上上次记录的序列的结尾权值 ,即此次dfs时得到的序列开头权值要与之比较的那一位;

  3. 参数三:\(res\),划分到此序列的答案;

如果\(res>ans\),即当前记录的答案大于之前的答案,直接返回,因为继续分割下去一定不是最优方案。

如果\(x=n+1\),即序列的\(n\)位已经分割完成,记录最终答案并返回。

定义\(i\)为变量,从第\(x\)位向第\(n\)位遍历,即选择\(x \sim i\)作为区间进行划分,对答案的贡献是\(sum[i-1]-sum[x-1]\)

  • 下标是\(i-1\)的原因为:对于\(sum[i]\)来说,对它的值有贡献的是\(sum[i-1]\)\(1\)(只有当\(a[i]<a[i+1]\)时);但此时是将\(i\)\(i+1\)分割,所以并没有\(1\)作为贡献,所以直接使用\(sum[i-1]\)进行答案贡献计算。
  • 下标为\(x-1\)的原因为:前缀和的计算。

特判:当\(a[x]>last\)时,即此次拼接对上一个序列的答案有贡献时,要对此次答案贡献加一。

代码

#include<bits/stdc++.h>
using namespace std;
int a[200010],sum[200010];
int ans;
int n;
void dfs(int x,int last,int res)
{
	if(res>=ans)
	{
	    return ;
	}
    if(x==n+1)
    {
        ans=min(ans,res);
        return;
    }
    for(int i=x;i<=n;i++)
    {
        int cnt=sum[i-1]-sum[x-1];
        if(a[x]>last)
        {
            cnt++;
        }
        dfs(i+1,a[x-1],res+cnt);
    }
}
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
	int T;
    cin>>T;
    while(T--)
    {
        a[0]=ans=INT_MAX;
        cin>>n;
        cin>>a[1];
        for(int i=2;i<=n;i++)
        {
            cin>>a[i];
            if(a[i]>a[i-1])
            {
                sum[i-1]=sum[i-2]+1;
            }
            else
            {
                sum[i-1]=sum[i-2];
            }
        }
        sum[n+1]=sum[n]=sum[n-1];
        dfs(1,INT_MAX,0);
        cout<<ans<<endl;
    }
    return 0;
}

正解100pts

思路(贪心)

观察题意可得答案的贡献只与相邻的数有关,因此我们只需要维护序列\(s\)\(t\)的结尾数字\(x\)\(y\)

因为要使\(p(s)+p(t)\)最小,所以要尽量使\(s\)\(t\)单调不增;

为使单调不增的元素更多(之后的数能够加入序列且产生更少的代价),即惩罚值更小,所以序列最后一个数越大越好

为更好维护,这里我们设\(x \leq y\);接着,让我们对输入的\(n\)\(jade\) \(seek\)(夹带私货)进行分类。

  • \(jade\) \(seek<x\)时,\(jade\) \(seek\)应放入\(s\)序列内,且不产生任何代价,更新\(x\)
  • \(jade\) \(seek>x\)\(jade\) \(seek \leq y\)时,\(jade\) \(seek\)应放入\(t\)序列内,且不产生任何代价,更新\(y\)
  • \(jade\) \(seek>y\)时,\(jade\) \(seek\)应放入\(s\)序列内,产生任何代价\(1\),更新\(s\),交换\(x\)\(y\)的值。(为保证最优性(即\(x\),\(y\)保持较大)这样更新可使较大的\(y\)保持不变且增大\(x\)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	freopen("divide.in","r",stdin);
    freopen("divide.out","w",stdout);
    int T;
    cin>>T;
    while(T--)
    {
    	int n;
    	cin>>n;
    	int x=0,y=0,ans=0;
    	for(int i=1;i<=n;i++)
    	{
    	    int jade_seek;
			cin>>jade_seek;
			if(jade_seek<=x)
			{
			    x=jade_seek;
			}	
		    else if(jade_seek>y)
			{
				if(x!=0)
				{
					ans++;
				}
				x=jade_seek;
			}
			else
			{
			    y=jade_seek;	
			} 
			if(x>y)
			{
				swap(x,y);
			}
		}
		cout<<ans<<endl; 
	}
    return 0; 
}

T2 ZZH与背包(knapsack)

洛谷 U142789 【1123T2】ZZH与背包

image

思路

因为\(n\leq 40\),所以使用折半搜索

输入序列后进行两次dfs,一次上界为\(\frac{n}{2}\),另一次上界为\(n\),算出所有方案即物体的体积所有可能组合。

与其他折半搜索不同的是,不要在第二次搜索时记录答案,而是用两个数组\(sum1\) \(sum2\)记录两次搜索的所有方案。后使用sort进行从小到大排序。

然后进行询问,对于每个\(l\)\(r\),都从小到大遍历\(sum1\),对于每个 \(sum1[i]\) 都使用双指针\(ll\),\(rr\)分别对\(l\) \(r\)进行\(sum2\)数组的匹配;

注意,因为\(sum1\),\(sum2\)序列都为有序的序列,所以对于从小到大遍历\(sum1\)\(sum2\)的值是单调不增的,即只需让\(ll\),\(rr\)指针从\(sum2\)数组的最后一位一直向左移到第一位。

对于每个\(sum1[i]\),它对答案的贡献为\(rr-ll\)

细节见代码

代码

#include<bits/stdc++.h>
using namespace std;
long long sum1[2000010],sum2[2000010];
long long a[45];
long long n,q,tot1,tot2;
void dfs1(long long x,long long s)
{
	if(x>n/2)
	{
		tot1++;
		sum1[tot1]=s;
		return ;
	}
	dfs1(x+1,s);
	dfs1(x+1,s+a[x]);
}
void dfs2(long long  x,long long s)
{
    if(x>n)
	{
	    tot2++;
	    sum2[tot2]=s;
	    return ;
	}
	dfs2(x+1,s);
	dfs2(x+1,s+a[x]);	
} 
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	freopen("knapsack.in","r",stdin);
    freopen("knapsack.out","w",stdout);
    cin>>n>>q;
    for(long long i=1;i<=n;i++)
    {
    	cin>>a[i];
	}
	dfs1(1,0);
	dfs2(n/2+1,0);
	sort(sum1+1,sum1+1+tot1);
	sort(sum2+1,sum2+1+tot2);
	sum2[0]=-1e18;
	sum2[tot2+1]=1e18; 
    while(q--)
    {
    	long long ans=0;
    	long long l,r;
    	cin>>l>>r;
    	long long bl1,ll=tot2+1,rr=tot2+1;
    	for(bl1=1;bl1<=tot1;bl1++)
    	{
    		while(sum1[bl1]+sum2[ll]>=l)
    		{
    			ll--;
			}
			while(sum1[bl1]+sum2[rr]>r)
			{
				rr--;
			}
			ans+=rr-ll;
		}
		cout<<ans<<endl;
	}
    return 0; 
}

T3 CF1914G2 Light Bulbs (Hard Version)

洛谷 CF1914G2 Light Bulbs (Hard Version)

正在施工中...

T4 [ABC313F] Flip Machines

洛谷 AT_abc313_f [ABC313F] Flip Machines

正在施工中...

posted @ 2025-08-20 20:33  BIxuan—玉寻  阅读(18)  评论(1)    收藏  举报