• Dollar Dayz poj3181


    http://poj.org/problem?id=3181

    这个题目一开始就能看出来是个dp问题,但是我并没有一开始就看出来是一个完全背包为题,只是想着根据以前的方法,这个问题应该是可以找到规律的,但是,还是被坑了,这还是一个大数问题!

    首先我膜拜一下hankcs大神的:

    ///////////////////////////////////////////////////////////

    1. #include <iostream>
    2. using namespace std;
    3.  
    4. unsigned long long dp[100 + 16][1000 + 16]; // dp[i][j] := 用i种价格配出金额j的方案数
    5.  
    6. ///////////////////////////SubMain//////////////////////////////////
    7. int main(int argc, char *argv[])
    8. {
    9. #ifndef ONLINE_JUDGE
    10.     freopen("in.txt", "r", stdin);
    11.     freopen("out.txt", "w", stdout);
    12. #endif
    13. int N, K;
    14. cin >> N >> K;
    15. dp[0][0] = 1;
    16. for (int i = 1; i <= K; ++i)
    17. {
    18. for (int k = 0; k <= N; k += i)
    19. {
    20. for (int j = N; j >= k; --j)
    21. {
    22. dp[i][j] += dp[- 1][- k];
    23. }
    24. }
    25. }
    26. cout << dp[K][N] << endl;
    27. #ifndef ONLINE_JUDGE
    28.     fclose(stdin);
    29.     fclose(stdout);
    30.     system("out.txt");
    31. #endif
    32.     return 0;
    33. }
    34. ////////////////////////////////////////////////////////////

      hancks的这个做法是用完全背包

      dp[i][j] = dp[i – 1][j] + dp[i – 1][j – i] + dp[i – 1][j – 2 * i] + … + dp[i – 1][0]

      由这个公式可以再递推:  

    将j换成j – i有

    dp[i][j – i] = dp[i – 1][j – i] + dp[i – 1][j – 2 * i] + … + dp[i – 1][0]

    得出:if j >= i:

      dp[i][j] = dp[i-1][j] + dp[i][j-i];

      我的做法是一开始就推出了这个公式,因为不小心看出了这个规律

        i:1->4 ,j :1->5 dp[i][j]规律是这样的

        1 1 1 1 1

        1 2 2 3 3

        1 2 3 4 5

        1 2 3 4 6     

        得出了j >= i : dp[i][j] = dp[i-1][j] + dp[i][j-i] 

        然而,这还是个大数问题,即使unsigned long long 都不行,开始一直没想通!

    /*************************************************************************
        > File Name: DollarDayz_poj3181.cpp
        > Author: spzhao
        > Mail: spzhaol@163.com 
        > Created Time: 2015年10月14日 星期三 11时13分22秒
     ************************************************************************/
    
    #include<iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    #define mod 10000000000000000
    using namespace std;
    
    const int N = 1005;
    const int K = 105;
    unsigned long long dp[100+16][1000+16][2];
    int n,k;
    void solve()
    {
    	for (int i = 1;i <= k;i++)
    	{
    		for (int j = 1;j <= n;j++)
    		{
    			if (j >= i)
    			{
    				dp[i][j][0] = dp[i-1][j][0]+dp[i][j-i][0];
    				dp[i][j][1] = dp[i-1][j][1]+dp[i][j-i][1];
    				dp[i][j][0] += dp[i][j][1]/mod;
    				dp[i][j][1] = dp[i][j][1]%mod;
    			}
    			else
    			{
    				dp[i][j][0] = dp[i-1][j][0];
    				dp[i][j][1] = dp[i-1][j][1];
    			}
    		}
    	}
    	if (dp[k][n][0])
    		cout << dp[k][n][0];
    	cout << dp[k][n][1] << endl;
    }
    int main ()
    {
    		cin >> n >> k;
    		memset(dp,0,sizeof(dp));
    		dp[1][0][1] = 1;
    		for (int i = 1;i <= k;i++)
    			dp[i][0][1] = 1;
    		solve();
    	return 0;
    }
    

      

     

  • 相关阅读:
    GNU make manual 翻译( 一百五十)
    [导入]Google开发者日见闻 王开源现身
    [导入]微软中国原高管宫力就任火狐中国总经理
    [导入]QQTalk Beta1 简体中文版
    [导入]《南方都市报》:国产龙芯产业化 难
    [导入][多图]Nokia正式发布奢华8600/6500双子手机
    [导入]用户界面设计的技巧与技术
    [导入]BitComet(比特彗星) 0.89
    [导入]µTorrent 1.7 beta 2248
    今天我注册了
  • 原文地址:https://www.cnblogs.com/ediszhao/p/4877997.html
Copyright © 2020-2023  润新知