题解:动态规划题,状态表示不是很好想,但状态转移感觉还行。
dp[i][j]:表示在加入第j个数字后,分成i段的最优解。
很容易想到,加入这个数,到底把它作为单独的一段还是和前面的一段合并,于是这两个状态就很容易去表示
易得状态转移方程:
dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][i-1],dp[i-1][i]…dp[i-1][j-1])+a[j]
发现dp只需当前状态和前一个状态的值,所以不妨用另外一个数组记录前一个状态最大值,这样就可以将二维数组减为一位数组。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf (1LL<<62)-1
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e3+10;
const int mod=998244353;
ll a[N],dp[N],maxx[N];
//dp[i][j]
int main(int argc, char *argv[]) {
int n,k;
ll ans;
cin >> n >> k;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
for(int i=1;i<=k;i++)
{
ans=-inf;
for(int j=i;j<=n;j++)
{
dp[j]=max(dp[j-1]+a[j],maxx[j-1]+a[j]);
maxx[j-1]=ans;
ans=max(ans,dp[j]);
}
}
cout << ans << endl;
}
题解:本题有一个很关键的知识点,0.123123123…=123/999,知道了这个,模拟去做就行,但貌似我写复杂了,还是菜啊~~
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0xffffff
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e6+10;
const int mod=998244353;
ll gcd(ll a,ll b) { return b==0? a : gcd(b,a%b); }
ll lcm(ll a,ll b) { return a*b/gcd(a,b); }
ll change(string s)
{
stringstream ss;
ss << s;
ll ans;
ss >> ans;
return ans;
}
int main(int argc, char *argv[]) {
string s;
int a;
cin >> s >> a;
int cnt=0,flag=0,plen=0,id;
for(int i=0;i<s.length();i++)
{
if(s[i]=='.')
{
flag=1;
plen=s.length()-1-i;
}
if(flag)
{
if(cnt==plen-a)
{
id=i;
break;
}
cnt++;
}
}
string s1=s.substr(s.length()-plen,cnt),s2=s.substr(id+1,s.length()-1-id);
string s3=s.substr(0,s.length()-1-plen);
ll inte=change(s3),dec=change(s2);
ll up1,up2,down1,down2=0;
if(s1=="")
{
up1=inte;
down1=1;
}
else
{
int inte_dec=change(s1);
up1=inte*pow(10, s1.length())+inte_dec;
down1=pow(10, s1.length());
}
up2=dec;
for(int i=0;i<s2.length();i++) down2=9*pow(10,i)+down2;
down2*=pow(10,cnt);
ll down=lcm(down1,down2);
ll up=down/down1*up1+down/down2*up2;
ll gg=gcd(up,down);
up/=gg;
down/=gg;
printf("%lld/%lld\n",up,down);
}
题面:给你k个飞机场,营业n天,有m个航班(出发地点、到达地点、出发时间、容量),n*k个时间点统计到飞机场的人数。
问是否每次航班能坐满,坐满则输出"optimal",否则"suboptimal".(如果必要可以把拉过去的人再拉回来。。O.O!)
题解:通过直接模拟来决这个问题。
用两个数组
b[i][j]:i机场第j天有多少人
a[i][j]:按照航班,i机场第j天能拉多少人。
对于每个机场每一天的航班进行模拟即可。
#include
using namespace std;
int a[25][25],b[25][25];
bool optimal = true;
void solve()
{
int k, n, m;
cin >> k >> n >> m;
for (int i = 0; i < m; ++i) {
int from, to, day, cap;
cin >> from >> to >> day >> cap;
a[from][day] += cap;
if (day + 1 <= n) b[to][day + 1] += cap;
}
for (int i = 0; i < k * n; ++i) {
int airport, day, num_people;
cin >> airport >> day >> num_people;
b[airport][day] += num_people;
}
for (int i = 1; i<=k; ++i) {
int now = 0;
for (int j = 1; j<=n; ++j) {
now += b[i][j];
if (now < a[i][j]) {
optimal = false;
return ;
}
now -= a[i][j];
}
}
}
int main() {
solve();
cout << (optimal ? "optimal" : "suboptimal") << endl;
}
n大于一定值就不会改变。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0xffffff
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e6+10;
const int mod=998244353;
lb f[10005];
void init()
{
f[0]=1;
for(int i=1;i<=100;i++)
f[i]=i*f[i-1];
}
int main(int argc, char *argv[]) {
init();
int n;
cin >> n;
lb ans=1;
if(n<=20)
{
for(int i=1;i<=n;i++)
{
ans+=1.0/f[i];
}
printf("%.15Lf",ans);
}
else cout << "2.718281828459045" << endl;
}
题解:题意可以理解为从点集合中找两点使得斜率最大,很容易想到斜率最大的两个点必定是连续的,所以按照x大小排序后,遍历两个连续点的斜率,取最大值即可。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0xffffff
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e6+10;
const int mod=998244353;
struct Node
{
double x,y;
}node[200005];
bool cmp(struct Node a,struct Node b)
{
return a.x < b.x;
}
int main(int argc, char *argv[]) {
int n;
cin >> n;
for(int i=0;i<n;i++)
cin >> node[i].x >> node[i].y;
sort(node,node+n,cmp);
lb ans=-1;
for(int i=1;i<n;i++)
{
lb tmp=fabs((node[i].y-node[i-1].y)/(node[i].x-node[i-1].x));
ans=max(ans,tmp);
}
printf("%.9Lf",ans);
}
题解:狼吃羊,羊吃草的经典问题
可以说是思维题
船的容量为k,从题中可知
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0xffffff
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e6+10;
const int mod=998244353;
int main(int argc, char *argv[]) {
int w,s,c,k;
cin >> w >> s >> c >> k;
if(k>min(s,w+c)) cout << "YES" << endl;
else if(k==min(s,w+c) && k>=max(s, w+c)) cout << "YES" << endl;
else cout << "NO" << endl;
}
题解:暴力出奇迹!
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define inf 0xffffff
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double lb;
typedef pair<int, int> pii;
typedef unsigned long long ull;
const long double PI = acos(-1);
const int N = 5e6+10;
const int mod=998244353;
int a[50];
bool judge(int num,int k)
{
int cnt=0;
while (num) {
a[cnt++]=num%k;
num/=k;
}
cnt--;
for(int i=0;i<=cnt/2;i++)
{
if(a[i]!=a[cnt-i]) return false;
}
return true;
}
int main(int argc, char *argv[]) {
int a,b,k;
cin >> a >> b >> k;
int ans=0;
for(int i=a;i<=b;i++)
{
int base=2;
for(;base<=k;base++)
{
if(!judge(i,base)) break;
}
if(base==k+1) ans++;
}
cout << ans ;
}