做了一下股票买卖,顺便把一串全部做了
股票买卖1
经典的模型:要求一次购买的最大的话,那么直接扫一下数列,然后对于每一个点减去他的前面的最小值即可,不断更新minv,同时用每个输入的x减去minv,同时更新ans。
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=int(l);i<int(r);i++)
#define per(i,r,l) for(int i=int(r-1);i>=int(l);i--)
#define repg(i,l,r) for(i=int(l);i<int(r);i++)
#define perg(i,r,l) for(int i=int(r-1);i>=int(l);i--)
#define rept(i,t) for(int i=int(h[t]);~i;i=ne[i])
#define reph(i,t,h) for(int i=int(h[t]);~i;i=ne[i])
#define x first
#define y second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef long long ll;
typedef unsigned long long lll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
const int INF=0x3f3f3f3f,mod=1e9+7;
const ll INFF=1e18;
const double eps=1e-9;
mt19937 mrand(random_device{}());
template<class A, class B> ostream& operator <<(ostream& out, const pair<A, B> &p) {
return out << "(" << p.x << " " << p.y << ")";
}
template<class A> ostream& operator <<(ostream& out, const vector<A> &v) {
rep(i, 0, sz(v)) {
if(i) out << " ";
out << v[i];
}
return out;
}
int rnd(int x){return mrand()%x;}
ll qmi(ll a,ll b){ll res=1;a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
ll qmul(ll a,ll b){ll res=0;a%=mod;while(b){if(b&1) res=(res+a)%mod;a=(a+a)%mod;b>>=1;} return res;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
/*ll read()
{
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=x*10+(c-'0'),c=getchar();
return f*x;
}*/
//#include <iostream>
//#include <cstdio>
//#include <windows.h>
//#include <cstdlib>
//#include <ctime>
//using namespace std;
//int main()
//{
// int ok = 0;
// int n = 50;
// for (int i = 1; i <= n; ++i)
// {
// system("make.exe > make.txt");
// system("std.exe < make.txt > std.txt");
// double begin = clock();
// system("baoli.exe < make.txt > baoli.txt");
// double end = clock();
//
// double t = (end - begin);
// if (system("fc std.txt baoli.txt"))
// {
// printf("测试点#%d Wrong Answer\n", i);
// }
// else if (t > 1000) //1秒
// {
// printf("测试点#%d Time Limited Exceeded 用时 %.0lfms\n", i, t);
// }
// else
// {
// printf("测试点#%d Accepted 用时%.0lfms\n", i, t);
// ok++; //AC数量+1
// }
// }
// printf("\n");
// double res = 100.0 * ok / n;
// printf("共 %d 组测试数据,AC数据 %d 组。 得分%.1lf。", n, ok, res);
//
// Sleep(1000); //休眠1秒,为了节约对拍次数。
//}
inline int read()
{
int x=0;
char ch;
bool fx=false;
do ch=getchar();while(~ch&&ch!='-'&&(ch<48||ch>57));
if(ch=='-')fx=true,ch=getchar();
for(;ch>47&&ch<58;ch=getchar())
x=(x<<1)+(x<<3)+(ch^48);
return fx?-x:x;
}
int n;
int ans;
int main()
{
#ifdef my_test
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
#ifdef my_dp
while(1)
{
system("data.exe > in.txt");
system("brute.exe < in.txt > brute.txt");
system("std.exe < in.txt > std.txt");
if(system("fc std.txt brute.txt"))
break;
}
#endif
#ifdef my_dp2
while (1) //一直循环,直到找到不一样的数据
{
system("data.exe");
system("baoli.exe");
system("std.exe");
if (system("fc std.txt baoli.txt")) //当 fc 返回1时,说明这时数据不一样
break; //不一样就跳出循环
}
#endif
clock_t start,end;
start=clock();
n=read();
int minv=INF;
rep(i,0,n)
{
int x;x=read();
ans=max(ans,x-minv);
minv=min(minv,x);
}
printf("%d\n",ans);
end=clock();
// printf("%lfms\n",(double)(end-start)/CLOCKS_PER_SEC*1000);
return 0;
}
股票买卖2
对购买次数没有加以限制
但是最多只能持有一只股票,这里就需要使用状态机来维护这个限制。
有股票和没股票在什么样的操作下可以到达什么样的状态。
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=int(l);i<int(r);i++)
#define per(i,r,l) for(int i=int(r-1);i>=int(l);i--)
#define repg(i,l,r) for(i=int(l);i<int(r);i++)
#define perg(i,r,l) for(int i=int(r-1);i>=int(l);i--)
#define rept(i,t) for(int i=int(h[t]);~i;i=ne[i])
#define reph(i,t,h) for(int i=int(h[t]);~i;i=ne[i])
#define x first
#define y second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef long long ll;
typedef unsigned long long lll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
const int INF=0x3f3f3f3f,mod=1e9+7;
const ll INFF=1e18;
const double eps=1e-9;
mt19937 mrand(random_device{}());
template<class A, class B> ostream& operator <<(ostream& out, const pair<A, B> &p) {
return out << "(" << p.x << " " << p.y << ")";
}
template<class A> ostream& operator <<(ostream& out, const vector<A> &v) {
rep(i, 0, sz(v)) {
if(i) out << " ";
out << v[i];
}
return out;
}
int rnd(int x){return mrand()%x;}
ll qmi(ll a,ll b){ll res=1;a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
ll qmul(ll a,ll b){ll res=0;a%=mod;while(b){if(b&1) res=(res+a)%mod;a=(a+a)%mod;b>>=1;} return res;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
/*ll read()
{
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=x*10+(c-'0'),c=getchar();
return f*x;
}*/
//#include <iostream>
//#include <cstdio>
//#include <windows.h>
//#include <cstdlib>
//#include <ctime>
//using namespace std;
//int main()
//{
// int ok = 0;
// int n = 50;
// for (int i = 1; i <= n; ++i)
// {
// system("make.exe > make.txt");
// system("std.exe < make.txt > std.txt");
// double begin = clock();
// system("baoli.exe < make.txt > baoli.txt");
// double end = clock();
//
// double t = (end - begin);
// if (system("fc std.txt baoli.txt"))
// {
// printf("测试点#%d Wrong Answer\n", i);
// }
// else if (t > 1000) //1秒
// {
// printf("测试点#%d Time Limited Exceeded 用时 %.0lfms\n", i, t);
// }
// else
// {
// printf("测试点#%d Accepted 用时%.0lfms\n", i, t);
// ok++; //AC数量+1
// }
// }
// printf("\n");
// double res = 100.0 * ok / n;
// printf("共 %d 组测试数据,AC数据 %d 组。 得分%.1lf。", n, ok, res);
//
// Sleep(1000); //休眠1秒,为了节约对拍次数。
//}
inline int read()
{
int x=0;
char ch;
bool fx=false;
do ch=getchar();while(~ch&&ch!='-'&&(ch<48||ch>57));
if(ch=='-')fx=true,ch=getchar();
for(;ch>47&&ch<58;ch=getchar())
x=(x<<1)+(x<<3)+(ch^48);
return fx?-x:x;
}
const int N=1e5+52;
int n,k;
int f[N][2];
int main()
{
#ifdef my_test
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
#ifdef my_dp
while(1)
{
system("data.exe > in.txt");
system("brute.exe < in.txt > brute.txt");
system("std.exe < in.txt > std.txt");
if(system("fc std.txt brute.txt"))
break;
}
#endif
#ifdef my_dp2
while (1) //一直循环,直到找到不一样的数据
{
system("data.exe");
system("baoli.exe");
system("std.exe");
if (system("fc std.txt baoli.txt")) //当 fc 返回1时,说明这时数据不一样
break; //不一样就跳出循环
}
#endif
clock_t start,end;
start=clock();
int t;
t=read();
while(t--)
{
memset(f,0,sizeof(f));
n=read();
f[0][1]=-INF;
rep(i,1,n+1)
{
int w;w=read();
f[i][0]=max(f[i-1][0],f[i-1][1]+w);f[i][1]=max(f[i-1][1],f[i-1][0]-w);
}
printf("%d\n",f[n][0]);
}
end=clock();
// printf("%lfms\n",(double)(end-start)/CLOCKS_PER_SEC*1000);
return 0;
}
股票买卖3
这里同样的也是状态机
只不过加上了次数限制
那么就有了多种状态
0从来没买过
1第一次买
2第一次卖
3第二次买
4第二次卖
转移也和上面的相同
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=int(l);i<int(r);i++)
#define per(i,r,l) for(int i=int(r-1);i>=int(l);i--)
#define repg(i,l,r) for(i=int(l);i<int(r);i++)
#define perg(i,r,l) for(int i=int(r-1);i>=int(l);i--)
#define rept(i,t) for(int i=int(h[t]);~i;i=ne[i])
#define reph(i,t,h) for(int i=int(h[t]);~i;i=ne[i])
#define x first
#define y second
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef long long ll;
typedef unsigned long long lll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;
const int INF=0x3f3f3f3f,mod=1e9+7;
const ll INFF=1e18;
const double eps=1e-9;
mt19937 mrand(random_device{}());
template<class A, class B> ostream& operator <<(ostream& out, const pair<A, B> &p) {
return out << "(" << p.x << " " << p.y << ")";
}
template<class A> ostream& operator <<(ostream& out, const vector<A> &v) {
rep(i, 0, sz(v)) {
if(i) out << " ";
out << v[i];
}
return out;
}
int rnd(int x){return mrand()%x;}
ll qmi(ll a,ll b){ll res=1;a%=mod;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;}
ll qmul(ll a,ll b){ll res=0;a%=mod;while(b){if(b&1) res=(res+a)%mod;a=(a+a)%mod;b>>=1;} return res;}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
/*ll read()
{
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=x*10+(c-'0'),c=getchar();
return f*x;
}*/
//#include <iostream>
//#include <cstdio>
//#include <windows.h>
//#include <cstdlib>
//#include <ctime>
//using namespace std;
//int main()
//{
// int ok = 0;
// int n = 50;
// for (int i = 1; i <= n; ++i)
// {
// system("make.exe > make.txt");
// system("std.exe < make.txt > std.txt");
// double begin = clock();
// system("baoli.exe < make.txt > baoli.txt");
// double end = clock();
//
// double t = (end - begin);
// if (system("fc std.txt baoli.txt"))
// {
// printf("测试点#%d Wrong Answer\n", i);
// }
// else if (t > 1000) //1秒
// {
// printf("测试点#%d Time Limited Exceeded 用时 %.0lfms\n", i, t);
// }
// else
// {
// printf("测试点#%d Accepted 用时%.0lfms\n", i, t);
// ok++; //AC数量+1
// }
// }
// printf("\n");
// double res = 100.0 * ok / n;
// printf("共 %d 组测试数据,AC数据 %d 组。 得分%.1lf。", n, ok, res);
//
// Sleep(1000); //休眠1秒,为了节约对拍次数。
//}
inline int read()
{
int x=0;
char ch;
bool fx=false;
do ch=getchar();while(~ch&&ch!='-'&&(ch<48||ch>57));
if(ch=='-')fx=true,ch=getchar();
for(;ch>47&&ch<58;ch=getchar())
x=(x<<1)+(x<<3)+(ch^48);
return fx?-x:x;
}
const int N=1e5+52;
int n;
int f[N][5];
int main()
{
#ifdef my_test
freopen(".in","r",stdin);
freopen(".out","w",stdout);
#endif
#ifdef my_dp
while(1)
{
system("data.exe > in.txt");
system("brute.exe < in.txt > brute.txt");
system("std.exe < in.txt > std.txt");
if(system("fc std.txt brute.txt"))
break;
}
#endif
#ifdef my_dp2
while (1) //一直循环,直到找到不一样的数据
{
system("data.exe");
system("baoli.exe");
system("std.exe");
if (system("fc std.txt baoli.txt")) //当 fc 返回1时,说明这时数据不一样
break; //不一样就跳出循环
}
#endif
clock_t start,end;
start=clock();
int t;
t=1;
while(t--)
{
memset(f,-0x3f,sizeof(f));//需要注意的是这里需要标记非法状态,因为如果非法状态合法参与进去的话,有可能这些非法状态的转移会比合法状态的转移来的更优
f[0][0]=0;//但是实际上这样的状态并不存在,也不存在这样的转移,所以需要标价非法状态
n=read();
rep(i,1,n+1)
{
int k;k=read();
f[i][0]=f[i-1][0];
f[i][1]=max(f[i-1][1],f[i-1][0]-k);
f[i][2]=max(f[i-1][1]+k,f[i-1][2]);
f[i][3]=max(f[i-1][2]-k,f[i-1][3]);
f[i][4]=max(f[i-1][3]+k,f[i-1][4]);
}
printf("%d\n",max(max(f[n][2],f[n][4]),f[n][0]));
}
end=clock();
// printf("%lfms\n",(double)(end-start)/CLOCKS_PER_SEC*1000);
return 0;
}