解题报告:Codeforces Round #433 (Div. 1) D. Michael and Charging Stations (DP)

题目链接

题意:

已知接下n天每天的消费ai

若某一天只使用现金,则可以得到10%的消费作为代金券

询问度过这n天的最小花费

n<=3e5,ai={1000,2000}


思路:

dp[x][y]:第 x 天手上有y金额的代金券所需的最小花费

将ai除以100以缩小第二维的大小,那么可以确定y<=10+20+1=31

因为使用代金券会无法得到代金券,所以每次使用时要尽可能的大

得到递推方程:

当只使用现金时:

使用代金券时:

总复杂度O(31*n)

代码:

#include<bits/stdc++.h>
#define INF dp[0][32]
const int N = 3e5+10;
using namespace std;

int n,A[N];
int dp[2][35];

int main()
{
   memset(dp,0x3f,sizeof(dp));
   scanf("%d",&n);
   for(int i=1;i<=n;++i){
      scanf("%d",&A[i]);A[i]/=100;
   }int s = 0 , t = 1;dp[0][0] = 0;
   for(int i=1;i<=n;++i){ int a = A[i] / 10;
      for(int j=0;j<=31;++j)if(dp[s][j]<INF){
         if(j+a<=31)dp[t][j+a] = min(dp[t][j+a],dp[s][j]+A[i]);
         int b = min(j,A[i]);
         if(b)dp[t][j-b] = min(dp[t][j-b],dp[s][j]+A[i]-b);
         dp[s][j] = INF;
      }swap(s,t);
   }int ans = INF;
   for(int i=0;i<20;++i)ans = min(ans,dp[s][i]);
   printf("%d00\n",ans);
   return 0;
}







阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32570675/article/details/77883132
文章标签: ACM dp
个人分类: 动态规划 Codeforces
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭