zoukankan      html  css  js  c++  java
  • UVALive

    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/116998

    Cent Savings

    Time Limit: 3000MS
    #### 问题描述 > To host a regional contest like NWERC a lot of > preparation is necessary: organizing rooms and > computers, making a good problem set, inviting > contestants, designing T-shirts, booking hotel > rooms and so on. I am responsible for going > shopping in the supermarket. > When I get to the cash register, I put all my > n items on the conveyor belt and wait until all > the other customers in the queue in front of me > are served. While waiting, I realize that this > supermarket recently started to round the total > price of a purchase to the nearest multiple of 10 > cents (with 5 cents being rounded upwards). For > example, 94 cents are rounded to 90 cents, while > 95 are rounded to 100. > It is possible to divide my purchase into groups and to pay for the parts separately. I managed to > find d dividers to divide my purchase in up to d + 1 groups. I wonder where to place the dividers to > minimize the total cost of my purchase. As I am running out of time, I do not want to rearrange items > on the belt. #### 输入 > The input file contains several test cases, each of them as described below. > The input consists of: > • one line with two integers n (1 ≤ n ≤ 2000) and d (1 ≤ d ≤ 20), the number of items and the > number of available dividers; > • one line with n integers p1, . . . , pn (1 ≤ pi ≤ 10000 for 1 ≤ i ≤ n), the prices of the items in > cents. The prices are given in the same order as the items appear on the belt. #### 输出 > For each test case, output the minimum amount of money needed to buy all the items, using up to d > dividers.

    样例

    sample input
    5 1
    13 21 55 60 42
    5 2
    1 1 1 1 1

    sample output
    190
    0

    题意

    给你一个数组,现在要把它最多切d刀分成d+1块,对每一块的和要四舍五入,问如果分割使得最后的和最大。

    题解

    各种姿势的dp:

    dp[i][j][k]表示前i个,切了j刀,最后一刀切完之后的值%10为k的舍入的最大偏差。
    则最后的结果=min(sum-dp[n][j][k])。

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define sz() size()
    #define pb(v) push_back(v)
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    
    const int maxn=2222;
    
    int n,d;
    
    int arr[maxn];
    int dp[maxn][22][11];
    
    inline int f(int x){
    	if(x<5) return x;
    	else return x-10; 
    }
    
    int main() {
    	while(scanf("%d%d",&n,&d)==2){
    		rep(i,0,maxn) rep(j,0,22) rep(k,0,11) dp[i][j][k]=-INF;
    		dp[0][0][0]=0;
    		int sum=0;
    		rep(i,1,n+1){
    			scanf("%d",&arr[i]); 
    			sum+=arr[i];
    		}
    		rep(i,0,n){
    			rep(j,0,d+1){
    				rep(k,0,10){
    					int nk=(arr[i+1]+k)%10;
    					dp[i+1][j][nk]=max(dp[i+1][j][nk],dp[i][j][k]-f(k)+f(nk));
    					
    					nk=arr[i+1]%10;
    					if(j+1<=d) dp[i+1][j+1][nk]=max(dp[i+1][j+1][nk],dp[i][j][k]+f(nk));
    				}
    			} 
    		}
    		int ma=f(sum%10);
    		rep(j,0,d+10){
    			rep(k,0,10){
    				ma=max(ma,dp[n][j][k]);
    			}
    		}
    		printf("%d
    ",sum-ma);
    	}
    	return 0;
    }
    

    dp[i][j]表示前i个切了j刀得到的最小和(刀切在i后面或不切)。

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define pb(v) push_back(v)
    #define sz() size()
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long  LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    
    //start----------------------------------------------------------------------
    
    const int maxn=2222;
    const int maxm=22;
    int n,d;
    int dp[maxn][maxm];
    int arr[maxn]; 
    
    int f(int x){
    	int t=x%10;
    	if(t>=5) x+=10;
    	x-=t;
    	return x;
    }
    
    int main() {
    	while(scanf("%d%d",&n,&d)==2){
    		clr(dp,0x3f);
    		dp[0][0]=0;
    		rep(i,1,n+1) scanf("%d",&arr[i]);
    		rep(i,1,n){
    			rep(j,0,d+1){
    				if(j==0) dp[i][j]=dp[i-1][j]+arr[i];
    				else dp[i][j]=min(dp[i-1][j]+arr[i],f(dp[i-1][j-1]+arr[i]));
    			}
    		}
    		int ans=INF;
    		rep(j,0,d+1) ans=min(ans,f(dp[n-1][j]+arr[n]));
    		printf("%d
    ",ans);
    	} 
    	return 0;
    }
    
    //end-----------------------------------------------------------------------
    

    dp[i][j]表示前i个切了j刀得到的最小和

    #include<map>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define X first
    #define Y second
    #define mkp make_pair
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define mid (l+(r-l)/2)
    #define pb(v) push_back(v)
    #define sz() size()
    #define all(o) (o).begin(),(o).end()
    #define clr(a,v) memset(a,v,sizeof(a))
    #define bug(a) cout<<#a<<" = "<<a<<endl
    #define rep(i,a,b) for(int i=a;i<(b);i++)
    
    typedef long long  LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<pair<int,int> > VPII;
    
    const int INF=0x3f3f3f3f;
    const LL INFL=0x3f3f3f3f3f3f3f3fLL;
    const double eps=1e-8;
    
    const int maxn=2222;
    const int maxm=22;
    int n,d;
    int dp[maxn][maxm];
    int arr[maxn],sumv[maxn]; 
    
    int f(int x){
        int t=x%10;
        if(t>=5) x+=10;
        x-=t;
        return x;
    }
    
    int main() {
        while(scanf("%d%d",&n,&d)==2){
            clr(dp,0x3f);
            dp[0][0]=0; sumv[0]=0;
            rep(i,1,n+1){
                scanf("%d",&arr[i]);
                sumv[i]=sumv[i-1]+arr[i];
                dp[i][0]=f(sumv[i]);
            }
            rep(i,1,n+1){
                rep(j,1,d+1){
                    rep(k,0,i){
                        dp[i][j]=min(dp[i][j],dp[k][j-1]+f(sumv[i]-sumv[k]));
                    }
                }
            }
            int ans=f(sumv[n]);
            rep(j,1,d+1) ans=min(ans,dp[n][j]);
            printf("%d
    ",ans);
        } 
        return 0;
    }
  • 相关阅读:
    Genbank简介
    Asc码与字符互相转化
    Netbeans中文乱码
    弹出警告窗口
    PHP代码执行漏洞总结
    透析SCN
    oracle用户管理的完全恢复4:在ARCHIVELOG 模式(恢复打开的数据库数据库最初是关闭的)
    Oracle用户管理的不完全恢复2:基于取消的恢复
    RMAN备份详解1
    oracle用户管理的完全恢复6:控制文件损坏(控制文件前后内容改变)
  • 原文地址:https://www.cnblogs.com/fenice/p/5751288.html
Copyright © 2011-2022 走看看