B. Cormen — The Best Friend Of a Man
题意:
给出某人原计划n天内各天遛狗的次数,但是要求任意相邻两天遛狗的次数要不小于k,求需要增加的遛狗的次数
思路:
dp[i][j] 表示 第i天 遛狗j次。如果某天遛狗次数小于原定计划的次数,则对答案的贡献为0。
Code:
#define ll long long
#define INF 0x3f3f3f3f
ll n, m, k;
ll dp[502][502]; // dp[i][j] 表示 第i天 遛狗j次
ll s[502];
ll pre[502][502];
void dfs(ll a, ll b){
if(a>1) dfs(a-1, pre[a][b]);
cout<<max(s[a], b)<<' ';
}
void work(){
cin>>n>>k;
for(int i=1;i<=n;++i) cin>>s[i];
s[0]=k;
memset(dp, 0x3f3f3f3f, sizeof(dp));
for(int i=0;i<=k;++i) dp[0][i]=0;
for(int i=1;i<=n;++i)
for(int j=0;j<=k;++j){
int nw=max(1ll*0, j-s[i]);
for(int t=k-j;t<=k;++t){ // 相邻两天遛狗的次数要不小于k,因此前一天最低要遛狗k-j次,最多k次
int x=nw+dp[i-1][t];
if(dp[i][j]>x){
dp[i][j]=x;
pre[i][j]=t;
}
}
}
ll ans=INF, pos;
for(int i=0;i<=k;++i){
if(ans>dp[n][i]) ans=dp[n][i], pos=i;
}
cout<<ans<<endl;
dfs(n, pos);
}```