stl 基础数据结构乱搞 (持续更新)

2018-8-25

ccpc-2018网络赛 A   buy and resell   hdu-6438   http://acm.hdu.edu.cn/showproblem.php?pid=6438 贪心,伪持续化  priority_queue   pair

题目大意:有n天,每天都可以进行买入(花费ai),卖出(收益ai-ak),什么都不干三种操作,问可以获得的最大收益和获得最大收益之下的最小交易次数(什么也不做不算交易次数)

初始思路:输入离散的点,贪心,寻找每一个最长上升段,用末尾元素-起始元素作为贡献,直到没有上升段为止。

如果是朴素算法面对一个纯上升序列的数据复杂度O(n^2)gg

算法优化:在线处理,考虑当前状态的最优解,由于每次求上升段用的是起始元素和末尾元素,考虑将数据用上升优先队列来存储,每次输入新的元素,如果队列不为空的话,用其和最高优先度(最小)的元素作比较

贪心,最优的方案一定是买和卖次数相同,我们每次考虑当前点的卖出,然后往前找最优的买入点,同时,最优的方案可能有多个,但是最优的结果只有一个(1,2,3,4这样的数据用1-4,2-3配对和1-3,2-4这样配对产生的收益相同)

如果该元素小于等于最高优先度的元素,那么在这个点卖出不会对最大收益产生任何贡献,将其加入队列

如果大于最高优先度的元素

这个时候关键点来了,当前最高收益不一定是整个结果的最优方案,比如 2 5 7这样的数据,所以想得到最优的方案,必须要对数据的存储进行处理,达到可以反悔的效果,从而得到最优方案

将这个队列的存储元素改为pair fir的值为val,一旦新输入的元素和队首元素配对,pop出当前队首元素  ans+=now-q.top;然后push两次当前元素进队列,分别为{val,1},{val,2} 一旦这个元素成为队首,这样对首就有两个一样的fir值的pair,当前的贪心最优方案一定是和最小的元素配对,如果pair的sec值为1,表示可以反悔,也就是说 贡献改为 当前元素 和 和当前对首配对的老的队首(2333) ,交易次数不变 , 并且当前的对首还存在于队列,ans+=now-q.top();相当于找了一个中间点两次贡献等于这次操作的总贡献

回过头来想,如果没配对成功的话,只push一次,pair的sec值设为2,表示不能反悔。

如果遇到当前对首元素sec值为2,此时的贪心策略仍旧是选择队首元素进行新的一次买卖配对,而不是选择老对首更小的 。

总复杂度为O(nlogn),完美契合总数据 5e5 

#include<iostream>
#include<queue>
#include<cstring>
#define ll long long
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        priority_queue < pair<ll,ll>,vector<pair<ll,ll> > ,greater< pair<ll,ll> > > q;
        int n,time=0;
        ll ans=0;
        ll temp;
        cin>>n;
        while(n--)
        {
            cin>>temp;
            if(!q.empty()&&temp>q.top().first)
            {
                if(q.top().second==1)//反悔
                {
                    time--;
                }
                else//反悔的话 time不变,不反悔的话time+=2
                {
                    time++;
                }
                ans+=temp-q.top().first;//当前最大贡献
                time++;
                q.pop();
                q.push({temp,1});q.push({temp,2});
            }
            else// 队列为空或者该元素是当前队列中的最小元素
            {
                q.push({temp,2});
            }
        }
        cout<<ans<<' '<<time<<endl;
    }

    return 0;
}

 

codeforces #506_div3-C   http://codeforces.com/contest/1029/problem/C 模拟  multiset

题目大意:n个一维线段,给出每个线段的左右端点,问去掉一个线段之后,剩余n-1个线段的最大重合段[l,r] (这n-1个线段都有子集在[l,r]中)

思路:模拟,需要用到删除操作,并且同一个值可能有多个可能会影响结果的数据,开两个multiset存

开一个数组存放每组l,r循环遍历数组,每次删除这个线段, 当前最大重合段就是

min(right)-max(left),最后再把这组数据弄回去

#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <cmath>
#include <set>
#define ll long long
using namespace std;
multiset<int>l;
multiset<int>r;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    int L[300005];
    int R[300005];
    for(int i=1;i<=n;i++)
    {
        cin>>L[i]>>R[i];
        l.insert(L[i]);
        r.insert(R[i]);
    }
    multiset<int>::iterator iter;
    ll ans=0;
    for(int i=1;i<=n;i++)
    {
        ll temp;
        l.erase(l.find(L[i]));
        r.erase(r.find(R[i]));
        iter=l.end();iter--;
        temp=*r.begin()-*iter;
        ans=max(temp,ans);
        l.insert(L[i]);
        r.insert(R[i]);
    }
    cout<<ans<<endl;







    return 0;
}

 

codeforces #506_div3-Dhttp://codeforces.com/contest/1029/problem/D 思路转换  模拟    map数组 计数map 

题目大意:给定n个数和 k,n个数字任意组合 (123 5变为1235或5123)问有多少种组合满足组合后的数%p==0

两个数字拼凑可以理解成前一个数*后一个数的位数+后一个数

数字最大不超过10^9也就是数不超过9位

暴力,先统计每个数字的位数,把每个数字 *(1 10 100 ... 1e9)在mod k 的数字保存下来,转换为两个数的加法==k   

而n只有2e5  开10个map(写的时候map能开数组也是惊了) m[i][j]记录前面*i个10之后在mod k之下 结果为j的数量

 复杂度 O(nlogn) 再转化为遍历每个数字的不同num,在map里找有没有对应的k-num 注意这里是加法,不是乘法

#include<iostream>
#include<map>
using namespace std;
typedef long long LL;
const int maxn=200005;
map<int,int> mp[11];
int a[maxn];
int w[maxn];
int n,k,x,c;
int f[11];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];//存储原始输入的数
        x=a[i];
        c=0;
        while(x)
        {
            x/=10;
            c++;
        }
        w[i]=c;
        mp[c][a[i]%k]++;//mp[i][j]表示这个数字有i位,在 mod k 下余几
    }
    f[0]=1;
    for(int i=1;i<=10;i++)
    {
        f[i]=10LL*f[i-1]%k;
    }
    LL ans=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=10;j++)
        {
            x=(k-1LL*a[i]*f[j]%k)%k;
            if(mp[j].find(x)!=mp[j].end())
            {
                ans+=mp[j][x];
                if(a[i]%k==x&&w[i]==j)
                {
                    ans--;
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
竞赛题目#include <cstdio> #include <cstring> #include <ctype.h> #include <cstdlib> #include <cmath> #include <climits> #include <ctime> #include <iostream> #include <algorithm> #include <deque> #include <vector> #include <queue> #include <string> #include <map> #include <stack> #include <set> #include <numeric> #include <sstream> #include <iomanip> #include <limits> #define CLR(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef pair<string, int> psi; typedef pair<string, string> pss; const double PI = 3.14159265358979323846264338327; const double E = exp(1); const double eps = 1e-6; const int INF = 0x3f3f3f3f; const int maxn = 1e6 + 5; const int MOD = 1e9 + 7; int main() { int n; cin >> n; vector <int> v; int num; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.push_back(num); } cin >> n; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.erase(v.begin() + num - 1); } vector <int>::iterator it; for (it = v.begin(); it != v.end(); it++) { if (it != v.begin()) printf(" "); cout << *it; } cout << endl; } --------------------- 作者:Dup4 来源:CSDN 原文:https://blog.csdn.net/dup4plz/article/details/79666083 版权声明:本文为博主原创文章,转载请附上博文链接!#include <cstdio> #include <cstring> #include <ctype.h> #include <cstdlib> #include <cmath> #include <climits> #include <ctime> #include <iostream> #include <algorithm> #include <deque> #include <vector> #include <queue> #include <string> #include <map> #include <stack> #include <set> #include <numeric> #include <sstream> #include <iomanip> #include <limits> #define CLR(a) memset(a, 0, sizeof(a)) using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; typedef pair <int, int> pii; typedef pair <ll, ll> pll; typedef pair<string, int> psi; typedef pair<string, string> pss; const double PI = 3.14159265358979323846264338327; const double E = exp(1); const double eps = 1e-6; const int INF = 0x3f3f3f3f; const int maxn = 1e6 + 5; const int MOD = 1e9 + 7; int main() { int n; cin >> n; vector <int> v; int num; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.push_back(num); } cin >> n; for (int i = 0; i < n; i++) { scanf("%d", &num;); v.erase(v.begin() + num - 1); } vector <int>::iterator it; for (it = v.begin(); it != v.end(); it++) { if (it != v.begin()) printf(" "); cout << *it; } cout << endl; } --------------------- 作者:Dup4 来源:CSDN 原文:https://blog.csdn.net/dup4plz/article/details/79666083 版权声明:本文为博主原创文章,转载请附上博文链接!
基于PyTorch的Embedding和LSTM的自动写诗实验LSTM (Long Short-Term Memory) 是一种特殊的循环神经网络(RNN)架构,用于处理具有长期依赖关系的序列数据。传统的RNN在处理长序列时往往会遇到梯度消失或梯度爆炸的问题,导致无法有效地捕捉长期依赖。LSTM通过引入门控机制(Gating Mechanism)和记忆单元(Memory Cell)来克服这些问题。 以下是LSTM的基本结构和主要组件: 记忆单元(Memory Cell):记忆单元是LSTM的核心,用于存储长期信息。它像一个传送带一样,在整个链上运行,只有一些小的线性交互。信息很容易地在其上保持不变。 输入门(Input Gate):输入门决定了哪些新的信息会被加入到记忆单元中。它由当前时刻的输入和上一时刻的隐藏状态共同决定。 遗忘门(Forget Gate):遗忘门决定了哪些信息会从记忆单元中被丢弃或遗忘。它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 输出门(Output Gate):输出门决定了哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。同样地,它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 LSTM的计算过程可以大致描述为: 通过遗忘门决定从记忆单元中丢弃哪些信息。 通过输入门决定哪些新的信息会被加入到记忆单元中。 更新记忆单元的状态。 通过输出门决定哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。 由于LSTM能够有效地处理长期依赖关系,它在许多序列建模任务中都取得了很好的效果,如语音识别、文本生成、机器翻译、时序预测等。
CSDN IT狂飙上传的代码均可运行,功能ok的情况下才上传的,直接替换数据即可使用,小白也能轻松上手 【资源说明】 基于MATLAB实现的这个代码主要是研究手写数字的识别效率,用卷积神经网络算法来实现,用的是官方手写字体数据,能够显现百分之九十以上的识别率+使用说明文档 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2020b;若运行有误,根据提示GPT修改;若不会,私信博主(问题描述要详细); 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可后台私信博主; 4.1 期刊或参考文献复现 4.2 Matlab程序定制 4.3 科研合作 功率谱估计: 故障诊断分析: 雷达通信:雷达LFM、MIMO、成像、定位、干扰、检测、信号分析、脉冲压缩 滤波估计:SOC估计 目标定位:WSN定位、滤波跟踪、目标定位 生物电信号:肌电信号EMG、脑电信号EEG、心电信号ECG 通信系统:DOA估计、编码译码、变分模态分解、管道泄漏、滤波器、数字信号处理+传输+分析+去噪、数字信号调制、误码率、信号估计、DTMF、信号检测识别融合、LEACH协议、信号检测、水声通信 5、欢迎下载,沟通交流,互相学习,共同进步!
基于LSTM+CNN的自然语言处理,基于单维LSTM、多维LSTM时序预测算法和多元线性回归算法的预测模型LSTM (Long Short-Term Memory) 是一种特殊的循环神经网络(RNN)架构,用于处理具有长期依赖关系的序列数据。传统的RNN在处理长序列时往往会遇到梯度消失或梯度爆炸的问题,导致无法有效地捕捉长期依赖。LSTM通过引入门控机制(Gating Mechanism)和记忆单元(Memory Cell)来克服这些问题。 以下是LSTM的基本结构和主要组件: 记忆单元(Memory Cell):记忆单元是LSTM的核心,用于存储长期信息。它像一个传送带一样,在整个链上运行,只有一些小的线性交互。信息很容易地在其上保持不变。 输入门(Input Gate):输入门决定了哪些新的信息会被加入到记忆单元中。它由当前时刻的输入和上一时刻的隐藏状态共同决定。 遗忘门(Forget Gate):遗忘门决定了哪些信息会从记忆单元中被丢弃或遗忘。它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 输出门(Output Gate):输出门决定了哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。同样地,它也由当前时刻的输入和上一时刻的隐藏状态共同决定。 LSTM的计算过程可以大致描述为: 通过遗忘门决定从记忆单元中丢弃哪些信息。 通过输入门决定哪些新的信息会被加入到记忆单元中。 更新记忆单元的状态。 通过输出门决定哪些信息会从记忆单元中输出到当前时刻的隐藏状态中。 由于LSTM能够有效地处理长期依赖关系,它在许多序列建模任务中都取得了很好的效果,如语音识别、文本生成、机器翻译、时序预测等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值