目录
左移右移
思路:
代码:
买二增一
思路:
代码:
松散子序列
思路:
代码:
填充
思路:
代码 :
有奖问答
思路:
代码:
更小的数
思路:
代码:
左移右移
思路:
1、用权重的思路,初始权值为该数值
2、将改变权值初始为cval=n+1,当之后出现某数,
为L则,权值赋为-cval, cval++;
为R则,权值赋为cval,cval++。
3、最后根据权值排序
代码:
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{int num;int val;
}a[200010];
bool cmp(node a,node b)
{return a.val < b.val;
}
int main()
{int n, m;cin >> n >> m;for (int i = 1; i <= n; i++){a[i].num = i;a[i].val = i;}int cval = n + 1;while (m--){int t;char b;cin >> b >> t;if (b == 'L'){a[t].val = -cval;cval++;}else{a[t].val = cval;cval++;}}sort(a + 1, a + n + 1, cmp);for (int i = 1; i <= n; i++)cout << a[i].num << " ";
}
买二增一
思路:
1、用一个优先队列q(大根堆)存储价格
2、再用一个队列cost存储,每买两个可以赠送的最大价格,当cost的队头大于等于q的队头,说明该q队头价格可以赠送,直接出队。
3、用ans存储总价格
代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{priority_queue<ll> q, cost;int n,t;cin >> n;while (n--)cin >> t, q.push(t);ll ans = 0;while (!q.empty()){while (!cost.empty() && !q.empty() && cost.top() >= q.top())cost.pop(), q.pop();int maxp=0, minp=0;if (!q.empty())maxp = q.top(), q.pop();while (!cost.empty() && !q.empty() && cost.top() >= q.top())cost.pop(), q.pop();if (!q.empty())minp = q.top(), q.pop();//cout << maxp << " " << minp;ans += maxp + minp;cost.push(minp / 2);}cout << ans;
}
松散子序列
思路:
1、用一个动态规划
代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{string s;cin >> s;int dp[1000005] = { 0 };dp[0] = s[0] - 'a' + 1;dp[1] = max(dp[0], s[1] - 'a' + 1);for (int i = 2; i < s.length(); i++){dp[i] = max(dp[i - 1], dp[i - 2] + (s[i] - 'a' + 1));}cout << dp[s.length() - 1];
}
填充
思路:
1、用flag记录是否是00或者11子串
2、从第二个开始,用这一个与前一个比较是否相等(偶数比奇数)
代码 :
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{string s;cin >> s;int flag[10000005];ll ans = 0;for (int i =1; i < s.length(); i++){if (flag[i - 1])continue;if (s[i] == s[i - 1] || s[i - 1] == '?' || s[i] == '?'){flag[i] = 1;ans++;}}cout << ans;
}
有奖问答
思路:
1、用动态规划
2、分两种情况:
第一种:第i题没有做对,方案数等于i-1题的所有方案数和
第二种:第i题做对,得到j分,方案数等于上一题方案数得j-10分的方案数
3、当得分为70时,加上该可能的所有方案数
代码:
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
int main()
{ll ans = 0;int dp[35][100] = { 0 };dp[1][0] = dp[1][10] = 1;//第一题可能得10分或者0分for(int i=2;i<=30;i++)//从第二题开始到三十题for (int j = 0; j <= 90; j += 10)//0到90的方案数{if (j == 0)//该题没做对,方案数等于i-1题的所有方案数{for (int k = 0; k <= 90; k += 10){dp[i][0] += dp[i - 1][k];}}else//该题做对了,方案数等于上一题做完该题得多少分-10的方案数{dp[i][j] = dp[i - 1][j - 10];if (j == 70) ans += dp[i][j];//等于70,方案数加上}}cout << ans;
}
更小的数
思路:
1、用动态规划
代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
int main()
{string s;cin >> s;int dp[5010][5010];s = " " + s;for (int i = 2; i < s.length(); i++){for (int j = 1; j + i - 1 < s.length(); j++){int l = j, r = j + i - 1;if (s[l] == s[r])dp[l][r] = dp[l + 1][r - 1];else if (s[l] < s[r])dp[l][r] = 0;elsedp[l][r] = 1;}}ll ans = 0;for (int i = 1; i < s.length(); i++)for (int j = i; j < s.length(); j++)ans += dp[i][j];cout << ans;
}