今日总结2024/5/22

今日学习了状态机模型,明确他和状态压缩是两种不同的状态表示方式

islower(),isupper()函数用来判断字符是否为小写的大写字符

tolower(),toupper()来转换大小写

to_string()将数字转换为字符

明确了字符串为子序列元素的最长上升子序列写法,以及存最优路径的最长上升子序列

AcWing 1049. 大盗阿福

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。

这条街上一共有 N 家店铺,每家店中都有一些现金。

阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。

作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。

他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?

输入格式
输入的第一行是一个整数 T,表示一共有 T 组数据。

接下来的每组数据,第一行是一个整数 N ,表示一共有 N 家店铺。

第二行是 N 个被空格分开的正整数,表示每一家店铺中的现金数量。

每家店铺中的现金数量均不超过1000。

输出格式
对于每组数据,输出一行。

该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。

数据范围
1≤T≤50,
1≤N≤1e5

输入样例:
2
3
1 8 2
4
10 7 6 14
输出样例:
8
24
样例解释
对于第一组样例,阿福选择第2家店铺行窃,获得的现金数量为8。

对于第二组样例,阿福选择第1和4家店铺行窃,获得的现金数量为10+14=24。

通过本题我们发现,当前店铺抢不抢和前一家抢没抢有关,且状态划分比较复杂

我们可以把上一家店铺是否抢的状态都保存下来,来判断

#include <iostream>
#include <algorithm>
using namespace std;
const int N=110,M=1e6;
int w[N],f[N][2];

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		memset(f,0,sizeof f);
		f[0][0]=0,f[0][1]=-M;//不能取起始点0点所以初始化负无穷
		for(int i=1;i<=n;i++) cin>>w[i];
		for(int i=1;i<=n;i++){
			f[i][0]=max(f[i-1][0],f[i-1][1]);//上一个要么选,不选
			f[i][1]=f[i-1][0]+w[i];
		}
		cout<<max(f[n][1],f[n][0])<<'\n';
	}
	return 0;
}
Acwing 1057. 股票买卖 IV

给定一个长度为 N 的数组,数组中的第 i个数字表示一个给定股票在第 i天的价格。

设计一个算法来计算你所能获取的最大利润,你最多可以完成 k𝑘 笔交易。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。一次买入卖出合为一笔交易。

输入格式

第一行包含整数 N 和 k,表示数组的长度以及你可以完成的最大交易笔数。

第二行包含 N 个不超过 10000 的非负整数,表示完整的数组。

输出格式

输出一个整数,表示最大利润。

数据范围

1≤N≤1e5
1≤k≤100

参考思路

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=1e5+7;
int w[N],f[N][110][2];//第i天,已经进行j次交易,状态为k(手上有无这个股票),获得的最大利润


int main(){
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,k;cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>w[i];
    memset(f,-0x3f,sizeof f);//所以状态包括不合法的都初始化为负无穷
    f[0][0][0]=0;//从这个状态开始才行,第0天没股票也没有交易,从这个状态转移才合法
    
    for(int i=1;i<=n;i++)
    for(int j=0;j<=k;j++){
        f[i][j][0]=f[i-1][j][0];
        if(j>=1)//只有第一天之后才能卖出
        f[i][j][0]=max(f[i][j][0],f[i-1][j-1][1]+w[i]);//手上没股票
        f[i][j][1]=max(f[i-1][j][0]-w[i],f[i-1][j][1]);//手上有股票
    }
    int res=0;//枚举手上没有股票每次交易的最大价值
    for(int i=0;i<=k;i++)
    res=max(res,f[n][i][0]);
    
    cout<<res;
    return 0;
}

最长上升子序列优化模板

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
const int N=5e3+10;
int a[N],g[N];
string ans[N];

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	g[0]=-1e9;//取最小值
	int len=0;
	for(int i=1;i<=n;i++){
		int l=0,r=len;
		while(l<r){
			int mid=l+r+1>>1;
			if(g[mid]<a[i]) l=mid;
			else r=mid-1;
		}
		len=max(len,l+1);//找到第一个比自己小且最接近自己的下标l
		g[l+1]=a[i];
		ans[l+1]=ans[l]+to_string(a[i]);//保存最优方案
	}
	cout<<len<<'\n';
	cout<<ans[len];
	return 0;
}

 Dijkstra带权堆优化模板

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int h[N],ne[N],e[N],w[N],idx,dist[N];
bool visit[N];
typedef pair<int,int> PII;
int n,m,s;//n个点m条边s为起始点

void add(int a,int b,int c){
	e[idx]=b;
	w[idx]=c;
	ne[idx]=h[a];
	h[a]=idx++;
}

void dijkstra(int u){
	memset(dist,0x3f,sizeof dist);
	dist[u]=0;
	priority_queue<PII,vector<PII>,greater<PII>> q;
	q.push({0,u});//前面存距离,后面存入口
	while(q.size()){
		PII a=q.top();
		q.pop();
		int distance=a.first,enter=a.second;
		if(visit[enter]) continue;//如果访问过就跳过循环
		visit[enter]=true;//标记访问
		for(int i=h[enter];i!=-1;i=ne[i]){
			int j=e[i];//记住i存的才是下标
			if(dist[j]>distance+w[i]){
				dist[j]=distance+w[i];
				q.push({dist[j],j});
			}
		}
	}
}

int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n>>m>>s;
	memset(h,-1,sizeof h);
	for(int i=1;i<=m;i++){
		int a,b,c;cin>>a>>b>>c;
		add(a,b,c);
	}
	dijkstra(s);
	for(int i=1;i<=n;i++) cout<<dist[i]<<' ';
	return 0;
}
//参考yxc大佬代码
AcWing 1058. 股票买卖 V

给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
输入格式
第一行包含整数 N,表示数组长度。

第二行包含 N 个不超过 10000 的正整数,表示完整的数组。

输出格式
输出一个整数,表示最大利润。

数据范围
1≤N≤1e5

输入样例

5
1 2 3 0 2
输出样例

3

来自yxc大佬的分析法

因此我们可以看出状态机入口为手中无货第二天,因为第一天可以买股票,因此要将f[i,0]和f[i,1]初始化为-0x3f3f3f3f(负无穷)然后出口是手中无货第一天和手中无货第二天,二者取一个最大值即可

#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+7;
int w[N],f[N][3];//第i天状态为j的最大利润

int main(){
	int n;cin>>n;
	for(int i=1;i<=n;i++) cin>>w[i];
	f[0][0]=f[0][1]=-0x3f3f3f3f;
	for(int i=1;i<=n;i++){
		f[i][0]=max(f[i-1][0],f[i-1][2]-w[i]);//手中有货
		f[i][1]=f[i-1][0]+w[i];//手中无货第一天
		f[i][2]=max(f[i-1][2],f[i-1][1]);//手中无货第二天
	}
	cout<<max(f[n][1],f[n][2]);
	return 0;
}
P8736 [2020 国 B] 游园安排
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+7;
string ans[N],str[N],f[N];//分别来存最长上升名字的字符串和分割好的名字

int main(){//分割大写名字
	string s;
	cin>>s;
	int cnt=0;
	for(auto x:s){
		if(isupper(x)){
			str[++cnt]=x;
		}else{
			str[cnt]+=x;
		}
	}
	//把str当作子序列,求最长上升子序列
	int len=0;
	for(int i=1;i<=cnt;i++){//上升子序列存最优路径模板
		int pos=lower_bound(f+1,f+len+1,str[i])-f;
		f[pos]=str[i];
		len=max(len,pos);
		ans[pos]=ans[pos-1]+str[i];
	}
	cout<<ans[len];//从零开始
	return 0;
}

用芯科的开发环境,通过zap加入.xml文件来加入私有属性,然后报错 Errors occurred during the build. Errors running builder 'Simplicity IDE Build' on project 'Z3Light_768_V5'. Multi-Exceptions available: Zap generation error: Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_REF, ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF, ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF 馃敡 Using temporary state directory: C:\Users\1\AppData\Local\Temp\zap.REZIPK 馃 ZAP generation started: 馃攳 input files: D:\SiliconLabs\Z3Light_768_V5\.\config\zcl 馃攳 output pattern: C:\Users\1\AppData\Local\Temp\apack_zclConfigurator1259056208456254490\output 馃攳 using templates: D:/SiliconLabs/SimplicityStudio/v5/developer/sdks/gecko-sdk-gsdk_4.4.3//protocol/zigbee/app/framework/gen-template/gen-templates.json,D:/SiliconLabs/SimplicityStudio/v5/developer/sdks/gecko-sdk-gsdk_4.4.3//extension/matter_extension/src/app/zap-templates/app-templates.json 馃攳 using zcl data: D:/SiliconLabs/SimplicityStudio/v5/developer/sdks/gecko-sdk-gsdk_4.4.3//app/zcl/zcl-zap.json,D:/SiliconLabs/SimplicityStudio/v5/developer/sdks/gecko-sdk-gsdk_4.4.3//extension/matter_extension/src/app/zap-templates/zcl/zcl.json 馃攳 zap version: ver. 2024.6.4, featureLevel 103, commit: 1cc9343d3dd1beeb01d9d33739131776687ce1ae from 2024-06-04T22:29:37.000Z, mode: binary, exe: D:\SiliconLabs\SimplicityStudio\v5\developer\adapter_packs\zap\zap-cli.exe 馃晲 Setup time: 3s 588ms 馃憠 using input file: D:\SiliconLabs\Z3Light_768_V5\config\zcl\zcl_config.zap [Error: SQLITE_CONSTRAINT: UNIQUE constraint failed: ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_REF, ENDPOINT_TYPE_ATTRIBUTE.ATTRIBUTE_REF, ENDPOINT_TYPE_ATTRIBUTE.ENDPOINT_TYPE_CLUSTER_REF] { errno: 19, code: 'SQLITE_CONSTRAINT' } 这是什么原因?
最新发布
03-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值