P3017 [USACO11MAR]Brownie Slicing G
思路:使巧克力最少的最多,联想到二分,二分(巧克力的最小值),l=min,r=所有相加,
check的判断条件虽然知道是与a,b判断,但怎么处理还是有些麻烦,先横向扫,对于满足<b,继续向下扫,不满足则减去
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define ms(x,y) memset(x,y,sizeof x);
#define YES cout<<"YES"<<'\n';
#define NO cout<<"NO"<<'\n';
#define endl cout<<'\n';
#define int long long
typedef long long ll;
const ll maxn=510,inf = 1e18 ;
const ll mod = 1e9 + 7;
using namespace std;
int s[maxn][maxn];
int s1[maxn][maxn];
int R, C, a, b;
bool check(int x) {
int now = 0, cnt = 0;
for (int i = 1; i <= R; i++){
int dis = 0, sum = 0; //sum记录横向
for (int j = 1; j <= C; j++) {
if (dis + (s1[i][j] - s1[i][j - 1]) - (s1[now][j] - s1[now][j - 1]) < x)
dis += (s1[i][j] - s1[i][j - 1]) - (s1[now][j] - s1[now][j - 1]);
else {
sum++;
dis = 0;
}
}
if (sum >= b){
now = i;
cnt++; //cnt记录竖向
}
}
return cnt >= a;
}
void solve(){
cin >> R >> C >> a >> b;
for (int i = 1; i <= R; i++) {
for (int j = 1; j <= C; j++) {
cin >> s[i][j];
s1[i][j] = s1[i][j] + s1[i - 1][j] + s1[i][j - 1] - s1[i - 1][j - 1]+s[i][j];
}
}
int l = 0, r = s1[R][C];
int ans = 0;
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid)) {
l = mid + 1;
ans = mid;
}
else {
r = mid - 1;
}
}
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
int t=1;
//cin >> t;
while (t--) {
solve();
}
}
D - Poisonous Full-Course
题意:英文题,翻一下,有0,1,2三种状态,遇0,1-》2,遇1-》2,0-》1,不能成为2状态
思路:dp,当遇到0,dp[i][1]只能由dp[i-1][1]转化而来,因为遇0,1-》0,dp[i][0]只能max(dp[i-1][1]+a[i].da, max(dp[i - 1][0], dp[i - 1][0] + a[i].da))从转化而来,遇到1, dp[i][1] = max(dp[i-1][1], dp[i-1][0] + a[i].da); dp[i][0] = dp[i - 1][0];以为不能连续1
总结:dp的过程就是找状态,当遇到一个状态向下一个状态有多种选择,且需最优时,dp合适,
这道题想到dp的话还是很容易推出状态的
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define ms(x,y) memset(x,y,sizeof x);
#define YES cout<<"YES"<<'\n';
#define NO cout<<"NO"<<'\n';
#define endl cout<<'\n';
#define int long long
typedef long long ll;
const ll maxn=3e5+10,inf = 1e18 ;
const ll mod = 1e9 + 7;
using namespace std;
struct node {
int f;
int da;
}a[maxn];
int dp[maxn][2];
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i].f >> a[i].da;
}
for (int i = 1; i <= n; i++) {
if (a[i].f == 0) {
dp[i][1] = dp[i-1][1];
dp[i][0] = max(dp[i-1][1]+a[i].da, max(dp[i - 1][0], dp[i - 1][0] + a[i].da));
}
else {
dp[i][1] = max(dp[i-1][1], dp[i-1][0] + a[i].da);
dp[i][0] = dp[i - 1][0];
}
}
cout << max(dp[n][0], dp[n][1]) << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
int t=1;
//cin >> t;
while (t--) {
solve();
}
}
总结:
这几天一直忙四级,课设,对刷题的进度耽误了,导致还没刷完(离散化,差分,前缀和题组),这周又要到考试周了,估计又要耽误,只能抓紧时间了