2023.2.24
逸一时,误一世,逸久怡久罢已龄。
小记:今天上了体育课...寒风中打哆嗦。不多说。最近好忙,今天两次电脑不知道碰到哪根线结果黑屏 + 关机...依旧不能写出来状态转移方程,背包模型忘了个干净。希望明天的模拟赛不要爆零。数学作业差评。另外找到了 U盘 里前机房留下的遗产,如 gyb 的 360 和 lz 给我拷过来的这个 vscode,虽然但是这个必须给好评,有点怀念,但是谢谢 gyb 和 lz。
今天做了 luogu P4158 粉刷匠、AcWing 281.硬币。这么少是因为太弱啦,真的不会啊。
1.洛谷 P4158 粉刷匠
关键:找到部分和个体的关系,然后不要被细节给弄晕,其实就那几个变量,根据变量的意义抽出来前一状态和后一状态的关系,设置好数组的含义。利用好背包模型捏。
#include<bits/stdc++.h>
using namespace std;
const int N = 55, M = 2510;
int n, m, t, ans = 0;
int a[N][N];
int f[N][M], g[N][M][N];
string s;
int main(){
scanf("%d%d%d", &n, &m, &t);
for(int i = 1; i <= n; i ++ ){
cin >> s;
for(int j = 0; j < m; j ++ ) a[i][j + 1] = a[i][j] + (s[j] == '1' ? 1 : 0);
}
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= m; j ++ )
for(int k = 1; k <= m; k ++ )
for(int q = j - 1; q < k; q ++ )
g[i][j][k] = max(g[i][j][k], g[i][j - 1][q] + max(a[i][k] - a[i][q], k - q - a[i][k] + a[i][q]));
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= t; j ++ )
for(int k = 0; k <= min(j, m); k ++ )
f[i][j] = max(f[i][j], f[i - 1][j - k] + g[i][k][m]);
printf("%d", f[n][t]);
return 0;
}
这个题是看的题解,但是题解里多了一步最后枚举涂的次数,其实大可不必,贪心的想当然是涂 t 次时有最优解。
2.AcWing 281.硬币 传送门
学长调数据了,被卡到了 20...不做评价,反正我自己也不会做依旧是看题解。。
分析好时间复杂度,一个略加优化的多重背包,主要的思想其实还是完全背包然后特判了一下物品的数量这样就省去了枚举个数,这样的。还是不会做。所以要好好背一下背包的模板...全忘了。
#include<bits/stdc++.h>
using namespace std;
int n, m;
int a[110], c[110];
int f[500010], used[1010];
int main()
{
while(cin >> n >> m)
{
for(int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for(int i = 1; i <= n; i ++ ) scanf("%d", &c[i]);
memset(f, 0, sizeof f);
memset(used, 0, sizeof used);
f[0] = 1;
for(int i = 1; i <= n; i ++ )
{
for(int j = 0; j <= m; j ++ ) used[j] = 0;
for(int j = a[i]; j <= m; j ++ )
if(!f[j] && f[j - a[i]] && used[j - a[i]] < c[i])
{
f[j] = 1;
used[j] = used[j - a[i]] + 1;
}
}
int ans = 0;
for(int i = 1; i <= m; i ++ ) if(f[i]) ans ++;
printf("%d\n", ans);
}
return 0;
}
没了。别的题没做,都是背包,我忘了。回去还得补数学作业啊无语。还好周六完了就是周天了...希望明天模拟赛不爆零。