Professional Documents
Culture Documents
struct item{
ll v,w;
};
item dp[maxn];
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int n,b;
cin>>n>>b;
item a[n];
ll s=0;
for(int i=0;i<n;++i){
cin>>a[i].w>>a[i].v;
s+=a[i].v;
memset(dp,INT_MAX,sizeof(dp));
dp[0].v=1;
//dp
for(ll j=s;j>=a[i].v;--j){
if(dp[j-a[i].v].v==1){
dp[j].v=1;
dp[j].w=min(a[i].w+dp[j-a[i].v].w,dp[j].w);
if(dp[i].v==1&&dp[i].w<=b&&dp[i].w>0){
cout<<i;break;
#include <bits/stdc++.h>
#define el cout<<'\n'
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
string s1,s2;
cin>>s1>>s2;
int n=s1.size(),m=s2.size();
int dp[n][m];
for(int i=0;i<n;++i){
for(int j=0;j<n;++j){
if(i==0||j==0) dp[i][j]=0;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
int len=dp[n][m],i=0,j=0;//o tung doan i va j thi se luu luon vao dp[i][j] nen
max da duoc cap nhat hoac vua moi duoc cap nhat
string ans="";
while(len){
if(s1[i]=s2[j]){
ans+=s1[i];
i++;j++;
len--;
}else
j++;
else
i++;
cout<<ans<<endl;
Nếu i==0 hoặc j==0 thì khởi tạo dp[0][j]=dp[i][0]=0 trường hợp cơ sở ở rìa đầu bên
trái của bảng
Sau vài tháng k học thì mình trở lại(thi hk dí sấp mặt)
Bài toán này có ý tưởng là quay lui(nếu bạn xem code trên magnj thì thấy có code đệ
quy có nhớ)
Ý tưởng là :chỉ số các phần tử trong 2 xâu nếu lưu trong dp thì sẽ +1 cho nó tự nhiên,
từng cái chỉ số trong dp là len đoạn con chung, lưu lại hết nhé
Các bạn sẽ k phải cần memset các phtu đều = 0 mà chỉ cần tạo biên = 0
Nếu 2 phần tử si=ti thì mảng sẽ lưu laij kết quả bằng cách lấy độ dài đoạn con chung
trước đó +1:dp[i-1][j-1]+1;
Ab(+1)c
A(+1)cd
Nếu mà chúng khác nhau thì sẽ vẫn cập nhật độ dài đến đó thôi(tư tưởng hay vl) bằng
cách dp[i][j]=max(dp[i-1][j],dp[i][j-1]) các bạn vẽ cây ra thì sẽ hiểu, hiểu đơn giản thì
nó còn 2 cái nhánh thì cập nhật 1 trong 2 nhánh đó
https://oj.vnoi.info/problem/atcoder_dp_g
#include<bits/stdc++.h>
#define maxn 100005
using namespace std;
vector<int> a[maxn];
int dp[maxn]={0};
int dfs(int u){
if(dp[u]) return dp[u];
for(auto x:a[u]){
dp[u]=max(dfs(x)+1,dp[u]);
}
return dp[u];
}
int main(){
int n,m;
cin>>n>>m;
for(int i=0;i<m;++i){
int x,y;
cin>>x>>y;
x--;y--;
a[x].push_back(y);
}
for(int i=0;i<n;++i){
dfs(i);
}
int ans=0;
for(int i=0;i<n;++i){
ans=max(ans,dp[i]);
}cout<<ans;
}
*code chẳng khác gì trên vnoj
Ý tưởng:
Gọi dp[u] là độ dài đoạn đường dài nhất có thể xuất phát từ đỉnh u
Duyệt dfs(u)
Neo: nếu dp[u]!=0 thì mới return u kiểu đã lấy đc độ dài r thì return là xong(trước đó
đã xử lý thì mới có len)
https://oj.vnoi.info/problem/atcoder_dp_k
Ý tưởng :
*Một vài chia sẻ của mình với bài toán này là ban đầu mình khá rush và đã
search sol nhưng mà thấy dòng recomend của gg thì nó hiện thêm từ knapsack ở
đằng sau nên đột nhiên mình nghĩ ra ý tưởng của bài knapsack khá hay nhưng
mà mình lại ngu ngu không biết code nên không biết phương án có khả thi hay
không