2023.6.19题解,总结

P3017 [USACO11MAR]Brownie Slicing G

2023.6.19题解,总结_第1张图片
思路:使巧克力最少的最多,联想到二分,二分(巧克力的最小值),l=min,r=所有相加,
check的判断条件虽然知道是与a,b判断,但怎么处理还是有些麻烦,先横向扫,对于满足

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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();
	}
}

总结:

这几天一直忙四级,课设,对刷题的进度耽误了,导致还没刷完(离散化,差分,前缀和题组),这周又要到考试周了,估计又要耽误,只能抓紧时间了

你可能感兴趣的:(c++,算法,开发语言)